annotate src/lib-index/mail-transaction-log-append.c @ 9458:adee8cb3ff5d HEAD

Minor memory allocation tweaks.
author Timo Sirainen <tss@iki.fi>
date Wed, 28 Oct 2009 14:10:04 -0400
parents 687ac828b964
children 3e1ca490dde0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 8292
diff changeset
1 /* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3470
346a494c2feb Moved array declaration to array-decl.h and include it in lib.h. So array.h
Timo Sirainen <tss@iki.fi>
parents: 3322
diff changeset
4 #include "array.h"
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "buffer.h"
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "write-full.h"
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "mail-index-private.h"
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "mail-index-view-private.h"
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
9 #include "mail-index-modseq.h"
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "mail-index-transaction-private.h"
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "mail-transaction-log-private.h"
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
13 struct log_append_context {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
14 struct mail_transaction_log_file *file;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
15 struct mail_index_transaction *trans;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
16 buffer_t *output;
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
17
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
18 uint64_t modseq;
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
19 uint32_t first_append_size;
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
20 bool sync_includes_this;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
21 };
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
22
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
23 static void log_append_buffer(struct log_append_context *ctx,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
24 const buffer_t *buf, const buffer_t *hdr_buf,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
25 enum mail_transaction_type type)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 struct mail_transaction_header hdr;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 uint32_t hdr_size;
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
29 size_t hdr_pos;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
32 i_assert((buf->used % 4) == 0);
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
33 i_assert(hdr_buf == NULL || (hdr_buf->used % 4) == 0);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
35 if (buf->used == 0)
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
36 return;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 memset(&hdr, 0, sizeof(hdr));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 hdr.type = type;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 if (type == MAIL_TRANSACTION_EXPUNGE)
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
6089
a19931ec66db Changed mail_transaction_begin() API to take flags parameter instead of two
Timo Sirainen <tss@iki.fi>
parents: 6074
diff changeset
42 if ((ctx->trans->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 hdr.type |= MAIL_TRANSACTION_EXTERNAL;
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
44 hdr.size = sizeof(hdr) + buf->used +
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
45 (hdr_buf == NULL ? 0 : hdr_buf->used);
7841
38cb76c22dc5 Update sync_highest_modseq while appending new transactions.
Timo Sirainen <tss@iki.fi>
parents: 7563
diff changeset
46
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
47 hdr_pos = ctx->output->used;
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
48 buffer_append(ctx->output, &hdr, sizeof(hdr));
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
49 if (hdr_buf != NULL)
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
50 buffer_append(ctx->output, hdr_buf->data, hdr_buf->used);
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
51 buffer_append(ctx->output, buf->data, buf->used);
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
52
9354
687ac828b964 lib-index: modseqs weren't tracked properly within session when changes were done.
Timo Sirainen <tss@iki.fi>
parents: 8941
diff changeset
53 if (mail_transaction_header_has_modseq(&hdr, buf->data, ctx->modseq))
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
54 ctx->modseq++;
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
55
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
56 /* update the size */
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
57 hdr_size = mail_index_uint32_to_offset(hdr.size);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
58 if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(ctx->file) &&
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
59 ctx->first_append_size == 0) {
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
60 /* size will be written later once everything
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
61 is in disk */
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
62 ctx->first_append_size = hdr_size;
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
63 hdr.size = 0;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
64 } else {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
65 hdr.size = hdr_size;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
66 }
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
67 buffer_write(ctx->output, hdr_pos, &hdr, sizeof(hdr));
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
68 }
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
69
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
70 static int log_buffer_move_to_memory(struct log_append_context *ctx)
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
71 {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
72 struct mail_transaction_log_file *file = ctx->file;
3833
318c70c1d4ec Beginnings of fallbacking to in-memory indexes when write fails with "out of
Timo Sirainen <tss@iki.fi>
parents: 3829
diff changeset
73
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
74 /* first we need to truncate this latest write so that log syncing
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
75 doesn't break */
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
76 if (ftruncate(file->fd, file->sync_offset) < 0) {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
77 mail_index_file_set_syscall_error(file->log->index,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
78 file->filepath,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
79 "ftruncate()");
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
80 }
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
81
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
82 if (mail_index_move_to_memory(file->log->index) < 0)
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
83 return -1;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
84 i_assert(MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
3833
318c70c1d4ec Beginnings of fallbacking to in-memory indexes when write fails with "out of
Timo Sirainen <tss@iki.fi>
parents: 3829
diff changeset
85
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
86 i_assert(file->buffer_offset + file->buffer->used ==
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
87 file->sync_offset);
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
88 buffer_append_buf(file->buffer, ctx->output, 0, (size_t)-1);
8292
9ed4ecd4a866 Fixes to handling "out of disk space/quota" write failures.
Timo Sirainen <tss@iki.fi>
parents: 8130
diff changeset
89 buffer_write(file->buffer, file->sync_offset - file->buffer_offset,
9ed4ecd4a866 Fixes to handling "out of disk space/quota" write failures.
Timo Sirainen <tss@iki.fi>
parents: 8130
diff changeset
90 &ctx->first_append_size, sizeof(uint32_t));
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
91 file->sync_offset = file->buffer_offset + file->buffer->used;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
92 return 0;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
93 }
3833
318c70c1d4ec Beginnings of fallbacking to in-memory indexes when write fails with "out of
Timo Sirainen <tss@iki.fi>
parents: 3829
diff changeset
94
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
95 static int log_buffer_write(struct log_append_context *ctx, bool want_fsync)
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
96 {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
97 struct mail_transaction_log_file *file = ctx->file;
3833
318c70c1d4ec Beginnings of fallbacking to in-memory indexes when write fails with "out of
Timo Sirainen <tss@iki.fi>
parents: 3829
diff changeset
98
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
99 if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
8941
eb9e5ab575a9 indexes: Error handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 8811
diff changeset
100 if (file->buffer == NULL) {
eb9e5ab575a9 indexes: Error handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 8811
diff changeset
101 file->buffer = buffer_create_dynamic(default_pool, 4096);
eb9e5ab575a9 indexes: Error handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 8811
diff changeset
102 file->buffer_offset = sizeof(file->hdr);
eb9e5ab575a9 indexes: Error handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 8811
diff changeset
103 }
5790
e1347a122140 Fixed in-memory indexes
Timo Sirainen <tss@iki.fi>
parents: 5749
diff changeset
104 buffer_append_buf(file->buffer, ctx->output, 0, (size_t)-1);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
105 file->sync_offset = file->buffer_offset + file->buffer->used;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
106 return 0;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
107 }
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
108
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
109 i_assert(ctx->first_append_size != 0);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
110 if (pwrite_full(file->fd, ctx->output->data, ctx->output->used,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
111 file->sync_offset) < 0) {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
112 /* write failure, fallback to in-memory indexes. */
5235
660763f5e75a If write fails with "not enough space" error, log it instead of silently
Timo Sirainen <tss@iki.fi>
parents: 5013
diff changeset
113 mail_index_file_set_syscall_error(file->log->index,
660763f5e75a If write fails with "not enough space" error, log it instead of silently
Timo Sirainen <tss@iki.fi>
parents: 5013
diff changeset
114 file->filepath,
660763f5e75a If write fails with "not enough space" error, log it instead of silently
Timo Sirainen <tss@iki.fi>
parents: 5013
diff changeset
115 "pwrite_full()");
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
116 return log_buffer_move_to_memory(ctx);
3833
318c70c1d4ec Beginnings of fallbacking to in-memory indexes when write fails with "out of
Timo Sirainen <tss@iki.fi>
parents: 3829
diff changeset
117 }
3243
40b4ba3c55b8 In-memory indexes work again. Just pass dir as NULL to mail_index_alloc().
Timo Sirainen <tss@iki.fi>
parents: 3215
diff changeset
118
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
119 i_assert(!ctx->sync_includes_this ||
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
120 file->sync_offset + ctx->output->used ==
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
121 file->max_tail_offset);
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
122
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
123 /* now that the whole transaction has been written, rewrite the first
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
124 record's size so the transaction becomes visible */
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
125 if (pwrite_full(file->fd, &ctx->first_append_size,
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
126 sizeof(uint32_t), file->sync_offset) < 0) {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
127 mail_index_file_set_syscall_error(file->log->index,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
128 file->filepath,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
129 "pwrite_full()");
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
130 return log_buffer_move_to_memory(ctx);
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
131 }
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
132
6796
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
133 if ((want_fsync && !file->log->index->fsync_disable) ||
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
134 file->log->index->nfs_flush) {
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
135 if (fdatasync(file->fd) < 0) {
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
136 mail_index_file_set_syscall_error(file->log->index,
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
137 file->filepath,
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
138 "fdatasync()");
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
139 return log_buffer_move_to_memory(ctx);
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
140 }
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
141 }
587a9d3054c1 If mail_nfs_index=yes, we need to call fdatasync() for all written
Timo Sirainen <tss@iki.fi>
parents: 6736
diff changeset
142
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
143 /* FIXME: when we're relying on O_APPEND and someone else wrote a
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
144 transaction, we'll need to wait for it to commit its transaction.
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
145 if it crashes before doing that, we'll need to overwrite it with
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
146 a dummy record */
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
147
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
148 file->sync_offset += ctx->output->used;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 return 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 static const buffer_t *
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3833
diff changeset
153 log_get_hdr_update_buffer(struct mail_index_transaction *t, bool prepend)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 buffer_t *buf;
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
156 const unsigned char *data, *mask;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 struct mail_transaction_header_update u;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 uint16_t offset;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 int state = 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 memset(&u, 0, sizeof(u));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
163 data = prepend ? t->pre_hdr_change : t->post_hdr_change;
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
164 mask = prepend ? t->pre_hdr_mask : t->post_hdr_mask;
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
165
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 buf = buffer_create_dynamic(pool_datastack_create(), 256);
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
167 for (offset = 0; offset <= sizeof(t->pre_hdr_change); offset++) {
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
168 if (offset < sizeof(t->pre_hdr_change) && mask[offset]) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 if (state == 0) {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 u.offset = offset;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 state++;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 } else {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 if (state > 0) {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 u.size = offset - u.offset;
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
176 buffer_append(buf, &u, sizeof(u));
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
177 buffer_append(buf, data + u.offset, u.size);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 state = 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 return buf;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
185 static void
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
186 ext_reset_update_atomic(struct mail_index_transaction *t,
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
187 uint32_t ext_id, uint32_t expected_reset_id)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
188 {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
189 const struct mail_index_ext *map_ext;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
190 struct mail_transaction_ext_reset *reset;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
191 uint32_t idx, reset_id;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
192
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
193 if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
194 /* new extension */
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
195 reset_id = 1;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
196 } else {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
197 map_ext = array_idx(&t->view->index->map->extensions, idx);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
198 reset_id = map_ext->reset_id + 1;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
199 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
200 if (reset_id != expected_reset_id) {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
201 /* ignore this extension update */
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
202 mail_index_ext_set_reset_id(t, ext_id, 0);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
203 return;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
204 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
205
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
206 if (reset_id == 0)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
207 reset_id++;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
208
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
209 array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
210
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
211 /* reseting existing data is optional */
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
212 if (array_is_created(&t->ext_resets)) {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
213 reset = array_idx_modifiable(&t->ext_resets, ext_id);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
214 if (reset->new_reset_id == (uint32_t)-1)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
215 reset->new_reset_id = reset_id;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
216 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
217 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
218
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
219 static void
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
220 transaction_update_atomic_reset_ids(struct mail_index_transaction *t)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
221 {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
222 const uint32_t *expected_reset_ids;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
223 unsigned int ext_id, count;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
224
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
225 if (!array_is_created(&t->ext_reset_atomic))
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
226 return;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
227
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
228 expected_reset_ids = array_get(&t->ext_reset_atomic, &count);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
229 for (ext_id = 0; ext_id < count; ext_id++) {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
230 if (expected_reset_ids[ext_id] != 0) {
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
231 ext_reset_update_atomic(t, ext_id,
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
232 expected_reset_ids[ext_id]);
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
233 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
234 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
235 }
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
236
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
237 static void log_append_ext_intro(struct log_append_context *ctx,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
238 uint32_t ext_id, uint32_t reset_id)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239 {
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
240 struct mail_index_transaction *t = ctx->trans;
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
241 const struct mail_index_registered_ext *rext;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 struct mail_transaction_ext_intro *intro;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 buffer_t *buf;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 uint32_t idx;
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
245 unsigned int count;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246
6042
99aace97fb4e Removed extension intro caching, it doesn't currently work right.
Timo Sirainen <tss@iki.fi>
parents: 5999
diff changeset
247 i_assert(ext_id != (uint32_t)-1);
99aace97fb4e Removed extension intro caching, it doesn't currently work right.
Timo Sirainen <tss@iki.fi>
parents: 5999
diff changeset
248
5849
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
249 if (t->reset ||
8807
2a3fd0d46bc6 If indexes had been reset, extension changes may have been written wrong.
Timo Sirainen <tss@iki.fi>
parents: 8805
diff changeset
250 !mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 /* new extension */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 idx = (uint32_t)-1;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
255 rext = array_idx(&t->view->index->extensions, ext_id);
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
256 if (!array_is_created(&t->ext_resizes)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 intro = NULL;
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
258 count = 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 } else {
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4358
diff changeset
260 intro = array_get_modifiable(&t->ext_resizes, &count);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
261 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
262
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
263 buf = buffer_create_dynamic(pool_datastack_create(), 128);
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
264 if (ext_id < count && intro[ext_id].name_size != 0) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
265 /* we're resizing it */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
266 intro += ext_id;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
267
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
268 i_assert(intro->ext_id == idx);
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
269 intro->name_size = idx != (uint32_t)-1 ? 0 :
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
270 strlen(rext->name);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
271 buffer_append(buf, intro, sizeof(*intro));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
272 } else {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
273 /* generate a new intro structure */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
274 intro = buffer_append_space_unsafe(buf, sizeof(*intro));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
275 intro->ext_id = idx;
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
276 intro->hdr_size = rext->hdr_size;
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
277 intro->record_size = rext->record_size;
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
278 intro->record_align = rext->record_align;
8130
b97c3be33b04 Replaced "no extension resizing" flag with "no extension shrinking".
Timo Sirainen <tss@iki.fi>
parents: 7931
diff changeset
279 intro->flags = MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
280 intro->name_size = idx != (uint32_t)-1 ? 0 :
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
281 strlen(rext->name);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
282 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
283 if (reset_id != 0) {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
284 /* we're going to reset this extension in this transaction */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285 intro->reset_id = reset_id;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
286 } else if (idx != (uint32_t)-1) {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
287 /* use the existing reset_id */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
288 const struct mail_index_ext *map_ext =
8807
2a3fd0d46bc6 If indexes had been reset, extension changes may have been written wrong.
Timo Sirainen <tss@iki.fi>
parents: 8805
diff changeset
289 array_idx(&t->view->index->map->extensions, idx);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
290 intro->reset_id = map_ext->reset_id;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
291 } else {
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
292 /* new extension, reset_id defaults to 0 */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
293 }
3816
575c79a0aabc Cleanup: Created mail_index_registered_ext which is used for
Timo Sirainen <tss@iki.fi>
parents: 3542
diff changeset
294 buffer_append(buf, rext->name, intro->name_size);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
295 if ((buf->used % 4) != 0)
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
296 buffer_append_zero(buf, 4 - (buf->used % 4));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
298 if (ctx->file->sync_highest_modseq == 0 &&
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
299 strcmp(rext->name, MAIL_INDEX_MODSEQ_EXT_NAME) == 0) {
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
300 /* modseq tracking started */
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
301 ctx->file->sync_highest_modseq = 1;
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
302 }
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
303
6042
99aace97fb4e Removed extension intro caching, it doesn't currently work right.
Timo Sirainen <tss@iki.fi>
parents: 5999
diff changeset
304 log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_INTRO);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
305 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
306
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
307 static void
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
308 log_append_ext_hdr_update(struct log_append_context *ctx,
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
309 const struct mail_index_transaction_ext_hdr_update *hdr)
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
310 {
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
311 buffer_t *buf;
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
312 const unsigned char *data, *mask;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
313 struct mail_transaction_ext_hdr_update u;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
314 uint16_t offset;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
315 bool started = FALSE;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
316
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
317 memset(&u, 0, sizeof(u));
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
318
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
319 data = hdr->data;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
320 mask = hdr->mask;
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
321
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
322 buf = buffer_create_dynamic(pool_datastack_create(), 256);
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
323 for (offset = 0; offset <= hdr->alloc_size; offset++) {
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
324 if (offset < hdr->alloc_size && mask[offset] != 0) {
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
325 if (!started) {
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
326 u.offset = offset;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
327 started = TRUE;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
328 }
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
329 } else {
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
330 if (started) {
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
331 u.size = offset - u.offset;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
332 buffer_append(buf, &u, sizeof(u));
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
333 buffer_append(buf, data + u.offset, u.size);
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
334 started = FALSE;
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
335 }
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
336 }
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
337 }
7892
053d1aa325f6 mail_index_update_header_ext(): Don't crash if size isn't 32bit aligned.
Timo Sirainen <tss@iki.fi>
parents: 7841
diff changeset
338 if (buf->used % 4 != 0)
053d1aa325f6 mail_index_update_header_ext(): Don't crash if size isn't 32bit aligned.
Timo Sirainen <tss@iki.fi>
parents: 7841
diff changeset
339 buffer_append_zero(buf, 4 - buf->used % 4);
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
340 log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_HDR_UPDATE);
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
341 }
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
342
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
343 static void
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
344 mail_transaction_log_append_ext_intros(struct log_append_context *ctx)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
345 {
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
346 struct mail_index_transaction *t = ctx->trans;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
347 const struct mail_transaction_ext_intro *resize;
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
348 const struct mail_index_transaction_ext_hdr_update *hdrs;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
349 struct mail_transaction_ext_reset ext_reset;
5946
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
350 unsigned int update_count, resize_count, ext_count = 0;
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
351 unsigned int hdrs_count, reset_id_count, reset_count;
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
352 uint32_t ext_id, reset_id;
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
353 const struct mail_transaction_ext_reset *reset;
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
354 const uint32_t *reset_ids;
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4358
diff changeset
355 const ARRAY_TYPE(seq_array) *update;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
356 buffer_t *buf;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
357
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
358 if (!array_is_created(&t->ext_rec_updates)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
359 update = NULL;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
360 update_count = 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
361 } else {
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
362 update = array_get(&t->ext_rec_updates, &update_count);
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
363 ext_count = update_count;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
364 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
365
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
366 if (!array_is_created(&t->ext_resizes)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
367 resize = NULL;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
368 resize_count = 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
369 } else {
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
370 resize = array_get(&t->ext_resizes, &resize_count);
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
371 if (ext_count < resize_count)
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
372 ext_count = resize_count;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
373 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
374
5946
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
375 if (!array_is_created(&t->ext_reset_ids)) {
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
376 reset_ids = NULL;
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
377 reset_id_count = 0;
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
378 } else {
5982
3e7364f200aa mail_index_ext_set_reset_id() handling fix
Timo Sirainen <tss@iki.fi>
parents: 5954
diff changeset
379 reset_ids = array_get(&t->ext_reset_ids, &reset_id_count);
5946
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
380 }
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
381
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
382 if (!array_is_created(&t->ext_resets)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
383 reset = NULL;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384 reset_count = 0;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385 } else {
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
386 reset = array_get(&t->ext_resets, &reset_count);
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
387 if (ext_count < reset_count)
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
388 ext_count = reset_count;
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
389 }
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
390
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
391 if (!array_is_created(&t->ext_hdr_updates)) {
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
392 hdrs = NULL;
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
393 hdrs_count = 0;
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
394 } else {
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
395 hdrs = array_get(&t->ext_hdr_updates, &hdrs_count);
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
396 if (ext_count < hdrs_count)
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
397 ext_count = hdrs_count;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
398 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
399
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400 memset(&ext_reset, 0, sizeof(ext_reset));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
401 buf = buffer_create_data(pool_datastack_create(),
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
402 &ext_reset, sizeof(ext_reset));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
403 buffer_set_used_size(buf, sizeof(ext_reset));
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
404
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405 for (ext_id = 0; ext_id < ext_count; ext_id++) {
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
406 if (ext_id < reset_count)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
407 ext_reset = reset[ext_id];
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
408 else
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
409 ext_reset.new_reset_id = 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
410 if ((ext_id < resize_count && resize[ext_id].name_size) ||
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
411 (ext_id < update_count &&
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
412 array_is_created(&update[ext_id])) ||
5897
3ec9ce7cd5e7 Implemented mail_index_update_header_ext()
Timo Sirainen <tss@iki.fi>
parents: 5849
diff changeset
413 ext_reset.new_reset_id != 0 ||
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
414 (ext_id < hdrs_count && hdrs[ext_id].alloc_size > 0)) {
5991
5dacddf4a88a When resetting extensions, the ext intro's reset_id must be the old one.
Timo Sirainen <tss@iki.fi>
parents: 5982
diff changeset
415 reset_id = ext_id < reset_id_count &&
5dacddf4a88a When resetting extensions, the ext intro's reset_id must be the old one.
Timo Sirainen <tss@iki.fi>
parents: 5982
diff changeset
416 ext_reset.new_reset_id == 0 ?
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
417 reset_ids[ext_id] : 0;
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
418 log_append_ext_intro(ctx, ext_id, reset_id);
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
419 }
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
420 if (ext_reset.new_reset_id != 0) {
5991
5dacddf4a88a When resetting extensions, the ext intro's reset_id must be the old one.
Timo Sirainen <tss@iki.fi>
parents: 5982
diff changeset
421 i_assert(ext_id < reset_id_count &&
5dacddf4a88a When resetting extensions, the ext intro's reset_id must be the old one.
Timo Sirainen <tss@iki.fi>
parents: 5982
diff changeset
422 ext_reset.new_reset_id == reset_ids[ext_id]);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
423 log_append_buffer(ctx, buf, NULL,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
424 MAIL_TRANSACTION_EXT_RESET);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
425 }
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
426 if (ext_id < hdrs_count && hdrs[ext_id].alloc_size > 0) {
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
427 T_BEGIN {
7896
efb782e078b9 mail_index_update_header_ext() can now be called multiple times for the same
Timo Sirainen <tss@iki.fi>
parents: 7895
diff changeset
428 log_append_ext_hdr_update(ctx, &hdrs[ext_id]);
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
429 } T_END;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6796
diff changeset
430 }
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
431 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
432 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
433
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
434 static void log_append_ext_rec_updates(struct log_append_context *ctx)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
435 {
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
436 struct mail_index_transaction *t = ctx->trans;
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4358
diff changeset
437 ARRAY_TYPE(seq_array) *updates;
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
438 const uint32_t *reset_ids;
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
439 unsigned int ext_id, count, reset_id_count;
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
440 uint32_t reset_id;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
441
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
442 if (!array_is_created(&t->ext_rec_updates)) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
443 updates = NULL;
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
444 count = 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
445 } else {
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4358
diff changeset
446 updates = array_get_modifiable(&t->ext_rec_updates, &count);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
447 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
448
5946
19bc2a4b3669 Added mail_index_ext_set_reset_id().
Timo Sirainen <tss@iki.fi>
parents: 5897
diff changeset
449 if (!array_is_created(&t->ext_reset_ids)) {
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
450 reset_ids = NULL;
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
451 reset_id_count = 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
452 } else {
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
453 reset_ids = array_get_modifiable(&t->ext_reset_ids,
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
454 &reset_id_count);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
455 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
456
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
457 for (ext_id = 0; ext_id < count; ext_id++) {
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
458 if (!array_is_created(&updates[ext_id]))
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459 continue;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460
5954
b788251996e5 Fixes to handling reset_id changes.
Timo Sirainen <tss@iki.fi>
parents: 5946
diff changeset
461 reset_id = ext_id < reset_id_count ? reset_ids[ext_id] : 0;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
462 log_append_ext_intro(ctx, ext_id, reset_id);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
464 log_append_buffer(ctx, updates[ext_id].arr.buffer, NULL,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
465 MAIL_TRANSACTION_EXT_REC_UPDATE);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
466 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
467 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
468
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
469 static void
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
470 log_append_keyword_update(struct log_append_context *ctx,
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
471 buffer_t *hdr_buf, enum modify_type modify_type,
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
472 const char *keyword, const buffer_t *buffer)
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
473 {
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
474 struct mail_transaction_keyword_update kt_hdr;
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
475
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
476 memset(&kt_hdr, 0, sizeof(kt_hdr));
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
477 kt_hdr.modify_type = modify_type;
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
478 kt_hdr.name_size = strlen(keyword);
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
479
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
480 buffer_set_used_size(hdr_buf, 0);
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
481 buffer_append(hdr_buf, &kt_hdr, sizeof(kt_hdr));
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
482 buffer_append(hdr_buf, keyword, kt_hdr.name_size);
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
483 if ((hdr_buf->used % 4) != 0)
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
484 buffer_append_zero(hdr_buf, 4 - (hdr_buf->used % 4));
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
485
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
486 log_append_buffer(ctx, buffer, hdr_buf,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
487 MAIL_TRANSACTION_KEYWORD_UPDATE);
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
488 }
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
489
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
490 static enum mail_index_sync_type
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
491 log_append_keyword_updates(struct log_append_context *ctx)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
492 {
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
493 const struct mail_index_transaction_keyword_update *updates;
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
494 const char *const *keywords;
3191
0df3f5d71958 Changed many buffers to arrays. Cleans up the code a lot.
Timo Sirainen <tss@iki.fi>
parents: 3178
diff changeset
495 buffer_t *hdr_buf;
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
496 enum mail_index_sync_type change_mask = 0;
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
497 unsigned int i, count, keywords_count;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
498
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
499 hdr_buf = buffer_create_dynamic(pool_datastack_create(), 64);
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
500
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
501 keywords = array_get_modifiable(&ctx->trans->view->index->keywords,
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
502 &keywords_count);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
503 updates = array_get_modifiable(&ctx->trans->keyword_updates, &count);
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
504 i_assert(count <= keywords_count);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
505
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
506 for (i = 0; i < count; i++) {
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
507 if (array_is_created(&updates[i].add_seq)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
508 change_mask |= MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
509 log_append_keyword_update(ctx, hdr_buf,
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
510 MODIFY_ADD, keywords[i],
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
511 updates[i].add_seq.arr.buffer);
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
512 }
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
513 if (array_is_created(&updates[i].remove_seq)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
514 change_mask |= MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
515 log_append_keyword_update(ctx, hdr_buf,
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
516 MODIFY_REMOVE, keywords[i],
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
517 updates[i].remove_seq.arr.buffer);
3254
a2943c050571 Keywords are now stored in X-Keywords headers in mbox. Did several related
Timo Sirainen <tss@iki.fi>
parents: 3243
diff changeset
518 }
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
519 }
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
520 return change_mask;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
521 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
522
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
523 static void log_append_sync_offset_if_needed(struct log_append_context *ctx)
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
524 {
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
525 struct mail_transaction_header_update *u;
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
526 buffer_t *buf;
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
527 uint32_t offset;
5283
8f9af66ee313 If transaction log grows larger than 1MB, rotate it even if it was created
Timo Sirainen <tss@iki.fi>
parents: 5278
diff changeset
528
8811
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
529 /* Update the tail offsets only when committing the sync transaction.
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
530 Other transactions may not know the latest tail offset and might
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
531 end up shrinking it. (Alternatively the shrinking tail offsets could
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
532 just be ignored, which would probably work fine too.) */
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
533 if (!ctx->trans->sync_transaction)
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
534 return;
69ddd7c9c585 indexes: Fixes to handling shrinking tail offsets.
Timo Sirainen <tss@iki.fi>
parents: 8807
diff changeset
535
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
536 if (ctx->file->max_tail_offset == ctx->file->sync_offset) {
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
537 /* FIXME: when we remove exclusive log locking, we
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
538 can't rely on this. then write non-changed offset + check
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
539 real offset + rewrite the new offset if other transactions
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
540 weren't written in the middle */
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
541 ctx->file->max_tail_offset += ctx->output->used +
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
542 sizeof(struct mail_transaction_header) +
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
543 sizeof(*u) + sizeof(offset);
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
544 ctx->sync_includes_this = TRUE;
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
545 }
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
546 offset = ctx->file->max_tail_offset;
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
547
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
548 if (ctx->file->saved_tail_offset == offset)
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
549 return;
8805
3feb2afdd81f indexes: Make sure we don't shrink log_file_tail_offset.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
550 i_assert(offset > ctx->file->saved_tail_offset);
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
551
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
552 buf = buffer_create_static_hard(pool_datastack_create(),
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
553 sizeof(*u) + sizeof(offset));
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
554 u = buffer_append_space_unsafe(buf, sizeof(*u));
5749
420a386fa27a int/ext/mailbox sync offset changes: Combined mailbox and int offsets to
Timo Sirainen <tss@iki.fi>
parents: 5715
diff changeset
555 u->offset = offsetof(struct mail_index_header, log_file_tail_offset);
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
556 u->size = sizeof(offset);
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
557 buffer_append(buf, &offset, sizeof(offset));
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
558
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
559 log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_HEADER_UPDATE);
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
560 }
3296
c2b8904dc21b mmap_disable=yes: Transaction log might have been rotated before everything
Timo Sirainen <tss@iki.fi>
parents: 3254
diff changeset
561
6093
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
562 #define TRANSACTION_HAS_CHANGES(t) \
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
563 ((t)->log_updates || (t)->log_ext_updates || \
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
564 (array_is_created(&(t)->updates) && array_count(&(t)->updates) > 0))
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
565
5013
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
566 static int
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
567 mail_transaction_log_append_locked(struct mail_index_transaction *t,
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
568 uint32_t *log_file_seq_r,
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
569 uoff_t *log_file_offset_r)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
570 {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
571 enum mail_index_sync_type change_mask = 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
572 struct mail_index_view *view = t->view;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
573 struct mail_index *index;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
574 struct mail_transaction_log *log;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
575 struct mail_transaction_log_file *file;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
576 struct log_append_context ctx;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
577 uoff_t append_offset;
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
578 bool want_fsync;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
579
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
580 index = mail_index_view_get_index(view);
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
581 log = index->log;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
582
5849
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
583 if (t->reset) {
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
584 /* Reset the whole index, preserving only indexid. Begin by
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
585 rotating the log. We don't care if we skip some non-synced
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
586 transactions. */
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
587 if (mail_transaction_log_rotate(log, TRUE) < 0)
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
588 return -1;
6074
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
589
6093
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
590 if (!TRANSACTION_HAS_CHANGES(t)) {
6074
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
591 /* we only wanted to reset */
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
592 return 0;
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
593 }
5849
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
594 }
a9df50952600 Added support for resetting index.
Timo Sirainen <tss@iki.fi>
parents: 5790
diff changeset
595
5013
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
596 if (!index->log_locked) {
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
597 /* update sync_offset */
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
598 if (mail_transaction_log_file_map(log->head,
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
599 log->head->sync_offset,
5715
11d39b7f07ff Handle mail_transaction_log_file_map() == 0 failures.
Timo Sirainen <tss@iki.fi>
parents: 5689
diff changeset
600 (uoff_t)-1) <= 0)
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
601 return -1;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
602 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
603
7913
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
604 if (array_is_created(&t->ext_reset_atomic) || t->max_modseq != 0) {
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
605 if (mail_index_map(t->view->index,
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
606 MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0)
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
607 return -1;
7913
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
608 }
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
609 if (array_is_created(&t->ext_reset_atomic))
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
610 transaction_update_atomic_reset_ids(t);
7913
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
611 if (t->max_modseq != 0)
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
612 mail_index_transaction_check_conflicts(t);
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
613 if (!TRANSACTION_HAS_CHANGES(t)) {
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
614 /* we aborted all changes, nothing else to do */
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
615 return 0;
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
616 }
7913
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
617 /* finally convert all sequences to UIDs before we write them,
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
618 but after we've checked and removed conflicts */
e04513064165 CONDSTORE: STORE UNCHANGEDSINCE conflicts are now checked atomically.
Timo Sirainen <tss@iki.fi>
parents: 7896
diff changeset
619 mail_index_transaction_convert_to_uids(t);
7563
6de1aed24ce5 Added mail_index_ext_reset_inc() to atomically increase extension's
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
620
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
621 file = log->head;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
622
7841
38cb76c22dc5 Update sync_highest_modseq while appending new transactions.
Timo Sirainen <tss@iki.fi>
parents: 7563
diff changeset
623 i_assert(file->sync_offset >= file->buffer_offset);
5285
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
624
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
625 memset(&ctx, 0, sizeof(ctx));
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
626 ctx.file = file;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
627 ctx.trans = t;
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
628 ctx.output = buffer_create_dynamic(default_pool, 1024);
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
629 ctx.modseq = file->sync_highest_modseq;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
630
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
631 /* send all extension introductions and resizes before appends
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
632 to avoid resize overhead as much as possible */
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
633 mail_transaction_log_append_ext_intros(&ctx);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
634
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
635 if (t->pre_hdr_changed) {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
636 log_append_buffer(&ctx,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
637 log_get_hdr_update_buffer(t, TRUE),
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
638 NULL, MAIL_TRANSACTION_HEADER_UPDATE);
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
639 }
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
640 if (array_is_created(&t->appends)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
641 change_mask |= MAIL_INDEX_SYNC_TYPE_APPEND;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
642 log_append_buffer(&ctx, t->appends.arr.buffer, NULL,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
643 MAIL_TRANSACTION_APPEND);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
644 }
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
645 if (array_is_created(&t->updates)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
646 change_mask |= MAIL_INDEX_SYNC_TYPE_FLAGS;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
647 log_append_buffer(&ctx, t->updates.arr.buffer, NULL,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
648 MAIL_TRANSACTION_FLAG_UPDATE);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
649 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
650
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
651 if (array_is_created(&t->ext_rec_updates))
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
652 log_append_ext_rec_updates(&ctx);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
653
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
654 /* keyword resets before updates */
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
655 if (array_is_created(&t->keyword_resets)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
656 change_mask |= MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
657 log_append_buffer(&ctx, t->keyword_resets.arr.buffer,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
658 NULL, MAIL_TRANSACTION_KEYWORD_RESET);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
659 }
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
660 if (array_is_created(&t->keyword_updates))
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
661 change_mask |= log_append_keyword_updates(&ctx);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
662
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
663 if (array_is_created(&t->expunges)) {
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
664 /* non-external expunges are only requests, ignore them when
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
665 checking fsync_mask */
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
666 if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
667 change_mask |= MAIL_INDEX_SYNC_TYPE_EXPUNGE;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
668 log_append_buffer(&ctx, t->expunges.arr.buffer, NULL,
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
669 MAIL_TRANSACTION_EXPUNGE);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
670 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
671
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
672 if (t->post_hdr_changed) {
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
673 log_append_buffer(&ctx, log_get_hdr_update_buffer(t, FALSE),
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
674 NULL, MAIL_TRANSACTION_HEADER_UPDATE);
3322
49071cc19102 If UIDVALIDITY changes, don't invalidate the whole index. Just expunge all
Timo Sirainen <tss@iki.fi>
parents: 3296
diff changeset
675 }
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
676
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
677 /* NOTE: mailbox sync offset update must be the last change.
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
678 it may update the sync offset to include this transaction, so it
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
679 needs to know this transaction's size */
6089
a19931ec66db Changed mail_transaction_begin() API to take flags parameter instead of two
Timo Sirainen <tss@iki.fi>
parents: 6074
diff changeset
680 if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
5689
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
681 log_append_sync_offset_if_needed(&ctx);
c2362f144f15 Initial commit for major index file code cleanup.
Timo Sirainen <tss@iki.fi>
parents: 5657
diff changeset
682
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
683 if (file->sync_offset < file->last_size) {
5285
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
684 /* there is some garbage at the end of the transaction log
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
685 (eg. previous write failed). remove it so reader doesn't
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
686 break because of it. */
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
687 buffer_set_used_size(file->buffer,
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
688 file->sync_offset - file->buffer_offset);
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
689 if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
690 if (ftruncate(file->fd, file->sync_offset) < 0) {
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
691 mail_index_file_set_syscall_error(index,
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
692 file->filepath, "ftruncate()");
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
693 }
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
694 }
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
695 }
a09da370923d If write to transaction log fails, we may later need to truncate the file so
Timo Sirainen <tss@iki.fi>
parents: 5283
diff changeset
696
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
697 want_fsync = (view->index->fsync_mask & change_mask) != 0;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
698 append_offset = file->sync_offset;
6736
3e189cbb7e7a fsync transaction commits only if the transaction contains change types
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
699 if (log_buffer_write(&ctx, want_fsync) < 0) {
6414
a6a49d5efc59 Changed buffer_free() and buffer_free_without_data() APIs to take ** pointer
Timo Sirainen <tss@iki.fi>
parents: 6093
diff changeset
700 buffer_free(&ctx.output);
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
701 return -1;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
702 }
7931
502cfdcc5650 Keep modseqs as 1 until the first modseq ext intro record enables them.
Timo Sirainen <tss@iki.fi>
parents: 7913
diff changeset
703 file->sync_highest_modseq = ctx.modseq;
6414
a6a49d5efc59 Changed buffer_free() and buffer_free_without_data() APIs to take ** pointer
Timo Sirainen <tss@iki.fi>
parents: 6093
diff changeset
704 buffer_free(&ctx.output);
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
705
6089
a19931ec66db Changed mail_transaction_begin() API to take flags parameter instead of two
Timo Sirainen <tss@iki.fi>
parents: 6074
diff changeset
706 if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0) {
5653
965e401fcb7b mail_index_view_add_hidden_transaction() takes now a whole area parameter so
Timo Sirainen <tss@iki.fi>
parents: 5288
diff changeset
707 /* mark the area covered by this transaction hidden */
965e401fcb7b mail_index_view_add_hidden_transaction() takes now a whole area parameter so
Timo Sirainen <tss@iki.fi>
parents: 5288
diff changeset
708 mail_index_view_add_hidden_transaction(view, file->hdr.file_seq,
965e401fcb7b mail_index_view_add_hidden_transaction() takes now a whole area parameter so
Timo Sirainen <tss@iki.fi>
parents: 5288
diff changeset
709 append_offset, file->sync_offset - append_offset);
965e401fcb7b mail_index_view_add_hidden_transaction() takes now a whole area parameter so
Timo Sirainen <tss@iki.fi>
parents: 5288
diff changeset
710 }
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
711
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
712 *log_file_seq_r = file->hdr.file_seq;
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
713 *log_file_offset_r = file->sync_offset;
5655
501aab713b0d Write transactions with two pwrite() calls instead of lots of tiny ones.
Timo Sirainen <tss@iki.fi>
parents: 5653
diff changeset
714 return 0;
3148
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
715 }
d9327a3dbf97 forgot to add
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
716
5013
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
717 int mail_transaction_log_append(struct mail_index_transaction *t,
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
718 uint32_t *log_file_seq_r,
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
719 uoff_t *log_file_offset_r)
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
720 {
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
721 struct mail_index *index;
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
722 int ret;
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
723
6074
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
724 *log_file_seq_r = 0;
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
725 *log_file_offset_r = 0;
47536814b011 Don't crash if mail_index_reset() is the only change in transaction.
Timo Sirainen <tss@iki.fi>
parents: 6042
diff changeset
726
6093
76da3b271bcf Keep flag updates separately from transaction.log_updates flag, because the
Timo Sirainen <tss@iki.fi>
parents: 6089
diff changeset
727 if (!TRANSACTION_HAS_CHANGES(t) && !t->reset) {
5013
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
728 /* nothing to append */
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
729 return 0;
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
730 }
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
731
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
732 index = mail_index_view_get_index(t->view);
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
733 if (index->log_locked) {
6089
a19931ec66db Changed mail_transaction_begin() API to take flags parameter instead of two
Timo Sirainen <tss@iki.fi>
parents: 6074
diff changeset
734 i_assert((t->flags &
a19931ec66db Changed mail_transaction_begin() API to take flags parameter instead of two
Timo Sirainen <tss@iki.fi>
parents: 6074
diff changeset
735 MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0);
5013
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
736 } else {
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
737 if (mail_transaction_log_lock_head(index->log) < 0)
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
738 return -1;
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
739 }
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
740
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
741 ret = mail_transaction_log_append_locked(t, log_file_seq_r,
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
742 log_file_offset_r);
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
743
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
744 if (!index->log_locked)
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
745 mail_transaction_log_file_unlock(index->log->head);
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
746 return ret;
6c76ed030b60 Fixed a race condition in transaction log rotation, which could have caused
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
747 }