annotate src/lib-index/mail-index-map-read.c @ 22576:707ae9de3812

lib: istream-multiplex - Minor code cleanup Avoid propagating the error twice, and avoid any confusion about what "got" actually contains.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 05 Oct 2017 20:24:11 +0300
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21389
diff changeset
1 /* Copyright (c) 2003-2017 Dovecot authors, see the included COPYING file */
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "array.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "nfs-workarounds.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "mmap-util.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "read-full.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "mail-index-private.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "mail-index-sync-private.h"
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "mail-transaction-log-private.h"
21185
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
11 #include "ioloop.h"
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 static void mail_index_map_copy_hdr(struct mail_index_map *map,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 const struct mail_index_header *hdr)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 if (hdr->base_header_size < sizeof(map->hdr)) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 /* header smaller than ours, make a copy so our newer headers
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 won't have garbage in them */
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21221
diff changeset
19 i_zero(&map->hdr);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 memcpy(&map->hdr, hdr, hdr->base_header_size);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 } else {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 map->hdr = *hdr;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 /* FIXME: backwards compatibility, remove later. In case this index is
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 accessed with Dovecot v1.0, avoid recent message counter errors. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 map->hdr.unused_old_recent_messages_count = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 static int mail_index_mmap(struct mail_index_map *map, uoff_t file_size)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 struct mail_index *index = map->index;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 struct mail_index_record_map *rec_map = map->rec_map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 const struct mail_index_header *hdr;
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
35 const char *error;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 i_assert(rec_map->mmap_base == NULL);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 buffer_free(&rec_map->buffer);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 if (file_size > SSIZE_T_MAX) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 /* too large file to map into memory */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 mail_index_set_error(index, "Index file too large: %s",
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 index->filepath);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 rec_map->mmap_base = mmap(NULL, file_size, PROT_READ | PROT_WRITE,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 MAP_PRIVATE, index->fd, 0);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 if (rec_map->mmap_base == MAP_FAILED) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 rec_map->mmap_base = NULL;
21185
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
51 if (ioloop_time != index->last_mmap_error_time) {
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
52 index->last_mmap_error_time = ioloop_time;
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
53 mail_index_set_syscall_error(index, t_strdup_printf(
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
54 "mmap(size=%"PRIuUOFF_T")", file_size));
47e4d310445b lib-index: Limit mmap syscall errors in index to 1/s
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 21169
diff changeset
55 }
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 rec_map->mmap_size = file_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 hdr = rec_map->mmap_base;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 if (rec_map->mmap_size >
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 offsetof(struct mail_index_header, major_version) &&
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 hdr->major_version != MAIL_INDEX_MAJOR_VERSION) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 /* major version change - handle silently */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 return 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 if (rec_map->mmap_size < MAIL_INDEX_HEADER_MIN_SIZE) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 mail_index_set_error(index, "Corrupted index file %s: "
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 "File too small (%"PRIuSIZE_T")",
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 index->filepath, rec_map->mmap_size);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 return 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
75 if (!mail_index_check_header_compat(index, hdr, rec_map->mmap_size, &error)) {
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 /* Can't use this file */
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
77 mail_index_set_error(index, "Corrupted index file %s: %s",
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
78 index->filepath, error);
21192
482da9579356 lib-index: Handle invalid headers as "corruption", not "temporary error"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21185
diff changeset
79 return 0;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 rec_map->mmap_used_size = hdr->header_size +
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 hdr->messages_count * hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 if (rec_map->mmap_used_size <= rec_map->mmap_size)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 rec_map->records_count = hdr->messages_count;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 else {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 rec_map->records_count =
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 (rec_map->mmap_size - hdr->header_size) /
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 rec_map->mmap_used_size = hdr->header_size +
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 rec_map->records_count * hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 mail_index_set_error(index, "Corrupted index file %s: "
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 "messages_count too large (%u > %u)",
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 index->filepath, hdr->messages_count,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 rec_map->records_count);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 mail_index_map_copy_hdr(map, hdr);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 map->hdr_base = rec_map->mmap_base;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 rec_map->records = PTR_OFFSET(rec_map->mmap_base, map->hdr.header_size);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 return 1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 static int mail_index_read_header(struct mail_index *index,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 void *buf, size_t buf_size, size_t *pos_r)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 size_t pos;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 int ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 memset(buf, 0, sizeof(struct mail_index_header));
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 /* try to read the whole header, but it's not necessarily an error to
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 read less since the older versions of the index format could be
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 smaller. Request reading up to buf_size, but accept if we only got
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 the header. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 pos = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 do {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 ret = pread(index->fd, PTR_OFFSET(buf, pos),
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 buf_size - pos, pos);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 if (ret > 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 pos += ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 } while (ret > 0 && pos < sizeof(struct mail_index_header));
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 *pos_r = pos;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 return ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 static int
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 mail_index_try_read_map(struct mail_index_map *map,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 uoff_t file_size, bool *retry_r, bool try_retry)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 struct mail_index *index = map->index;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 const struct mail_index_header *hdr;
11310
2937ca64faa9 lib-index: Use IO_BLOCK_SIZE
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
136 unsigned char read_buf[IO_BLOCK_SIZE];
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
137 const char *error;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 const void *buf;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 void *data = NULL;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 ssize_t ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 size_t pos, records_size, initial_buf_pos = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 unsigned int records_count = 0, extra;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 i_assert(map->rec_map->mmap_base == NULL);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 *retry_r = FALSE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 ret = mail_index_read_header(index, read_buf, sizeof(read_buf), &pos);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 buf = read_buf; hdr = buf;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 if (pos > (ssize_t)offsetof(struct mail_index_header, major_version) &&
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 hdr->major_version != MAIL_INDEX_MAJOR_VERSION) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 /* major version change - handle silently */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 return 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 if (ret >= 0 && pos >= MAIL_INDEX_HEADER_MIN_SIZE &&
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 (ret > 0 || pos >= hdr->base_header_size)) {
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
158 if (!mail_index_check_header_compat(index, hdr, file_size, &error)) {
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 /* Can't use this file */
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
160 mail_index_set_error(index, "Corrupted index file %s: %s",
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
161 index->filepath, error);
21192
482da9579356 lib-index: Handle invalid headers as "corruption", not "temporary error"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21185
diff changeset
162 return 0;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 initial_buf_pos = pos;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 if (pos > hdr->header_size)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 pos = hdr->header_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 /* place the base header into memory. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 buffer_reset(map->hdr_copy_buf);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 buffer_append(map->hdr_copy_buf, buf, pos);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 if (pos != hdr->header_size) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 /* @UNSAFE: read the rest of the header into memory */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 data = buffer_append_space_unsafe(map->hdr_copy_buf,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 hdr->header_size -
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 pos);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 ret = pread_full(index->fd, data,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 hdr->header_size - pos, pos);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 if (ret > 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 /* header read, read the records now. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185 records_size = (size_t)hdr->messages_count * hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 records_count = hdr->messages_count;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 if (file_size - hdr->header_size < records_size ||
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
189 (hdr->record_size != 0 &&
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 records_size / hdr->record_size != hdr->messages_count)) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 records_count = (file_size - hdr->header_size) /
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 records_size = (size_t)records_count * hdr->record_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 mail_index_set_error(index, "Corrupted index file %s: "
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 "messages_count too large (%u > %u)",
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 index->filepath, hdr->messages_count,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197 records_count);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 if (map->rec_map->buffer == NULL) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 map->rec_map->buffer =
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 buffer_create_dynamic(default_pool,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 records_size);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206 /* @UNSAFE */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 buffer_set_used_size(map->rec_map->buffer, 0);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 if (initial_buf_pos <= hdr->header_size)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209 extra = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 else {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211 extra = initial_buf_pos - hdr->header_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 buffer_append(map->rec_map->buffer,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 CONST_PTR_OFFSET(buf, hdr->header_size),
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214 extra);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 if (records_size > extra) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217 data = buffer_append_space_unsafe(map->rec_map->buffer,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218 records_size - extra);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 ret = pread_full(index->fd, data, records_size - extra,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 hdr->header_size + extra);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 if (ret < 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 if (errno == ESTALE && try_retry) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 /* a new index file was renamed over this one. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227 *retry_r = TRUE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 return 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
229 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
230 mail_index_set_syscall_error(index, "pread_full()");
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
231 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233 if (ret == 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 mail_index_set_error(index,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235 "Corrupted index file %s: File too small",
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 index->filepath);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 return 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 map->rec_map->records =
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 buffer_get_modifiable_data(map->rec_map->buffer, NULL);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 map->rec_map->records_count = records_count;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 mail_index_map_copy_hdr(map, hdr);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 map->hdr_base = map->hdr_copy_buf->data;
20281
b961ec20493e lib-index: Added header-size asserts
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
246 i_assert(map->hdr_copy_buf->used == map->hdr.header_size);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247 return 1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249
15212
b7ac3897f3fd lib-index: dovecot.index file is no longer overwritten, so it doesn't need to be locked.
Timo Sirainen <tss@iki.fi>
parents: 14231
diff changeset
250 static int mail_index_read_map(struct mail_index_map *map, uoff_t file_size)
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 struct mail_index *index = map->index;
10000
c610321584ca Use array_foreach*() in some useful places.
Timo Sirainen <tss@iki.fi>
parents: 9696
diff changeset
253 mail_index_sync_lost_handler_t *const *handlerp;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254 struct stat st;
10000
c610321584ca Use array_foreach*() in some useful places.
Timo Sirainen <tss@iki.fi>
parents: 9696
diff changeset
255 unsigned int i;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
256 int ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 bool try_retry, retry;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 /* notify all "sync lost" handlers */
10000
c610321584ca Use array_foreach*() in some useful places.
Timo Sirainen <tss@iki.fi>
parents: 9696
diff changeset
260 array_foreach(&index->sync_lost_handlers, handlerp)
c610321584ca Use array_foreach*() in some useful places.
Timo Sirainen <tss@iki.fi>
parents: 9696
diff changeset
261 (**handlerp)(index);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
262
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
263 for (i = 0;; i++) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
264 try_retry = i < MAIL_INDEX_ESTALE_RETRY_COUNT;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
265 if (file_size == (uoff_t)-1) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
266 /* fstat() below failed */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
267 ret = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
268 retry = try_retry;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
269 } else {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
270 ret = mail_index_try_read_map(map, file_size,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
271 &retry, try_retry);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
272 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
273 if (ret != 0 || !retry)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
274 break;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
275
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
276 /* ESTALE - reopen index file */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
277 mail_index_close_file(index);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
278
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
279 ret = mail_index_try_open_only(index);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
280 if (ret <= 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
281 if (ret == 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
282 /* the file was lost */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
283 errno = ENOENT;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
284 mail_index_set_syscall_error(index, "open()");
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
286 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
287 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
288
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
289 if (fstat(index->fd, &st) == 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
290 file_size = st.st_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
291 else {
12936
d14b0fd0a423 Linux NFS: fstat() may return ENOENT instead of ESTALE in some kernel versions.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
292 if (!ESTALE_FSTAT(errno)) {
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
293 mail_index_set_syscall_error(index, "fstat()");
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
294 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
295 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
296 file_size = (uoff_t)-1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
298 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
299 return ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
300 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
301
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
302 /* returns -1 = error, 0 = index files are unusable,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
303 1 = index files are usable or at least repairable */
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
304 static int
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
305 mail_index_map_latest_file(struct mail_index *index, const char **reason_r)
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
306 {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
307 struct mail_index_map *old_map, *new_map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
308 struct stat st;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
309 uoff_t file_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
310 bool use_mmap, unusable = FALSE;
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
311 const char *error;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
312 int ret, try;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
313
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
314 *reason_r = NULL;
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
315
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
316 ret = mail_index_reopen_if_changed(index, reason_r);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
317 if (ret <= 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
318 if (ret < 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
319 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
320
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
321 /* the index file is lost/broken. let's hope that we can
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
322 build it from the transaction log. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
323 return 1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
324 }
17476
4a396f0c3b79 Added various asserts to try to silence Coverity false positives.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
325 i_assert(index->fd != -1);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
326
9696
126132cb1c19 index: Removed duplication of mail_index_open_flags from struct mail_index.
Timo Sirainen <tss@iki.fi>
parents: 9332
diff changeset
327 if ((index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0)
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
328 nfs_flush_attr_cache_fd_locked(index->filepath, index->fd);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
329
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
330 if (fstat(index->fd, &st) == 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
331 file_size = st.st_size;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
332 else {
12936
d14b0fd0a423 Linux NFS: fstat() may return ENOENT instead of ESTALE in some kernel versions.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
333 if (!ESTALE_FSTAT(errno)) {
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
334 mail_index_set_syscall_error(index, "fstat()");
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335 return -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
336 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
337 file_size = (uoff_t)-1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
338 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
339
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
340 /* mmaping seems to be slower than just reading the file, so even if
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
341 mmap isn't disabled don't use it unless the file is large enough */
9696
126132cb1c19 index: Removed duplication of mail_index_open_flags from struct mail_index.
Timo Sirainen <tss@iki.fi>
parents: 9332
diff changeset
342 use_mmap = (index->flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0 &&
126132cb1c19 index: Removed duplication of mail_index_open_flags from struct mail_index.
Timo Sirainen <tss@iki.fi>
parents: 9332
diff changeset
343 file_size != (uoff_t)-1 && file_size > MAIL_INDEX_MMAP_MIN_SIZE;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
344
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
345 new_map = mail_index_map_alloc(index);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
346 if (use_mmap) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
347 ret = mail_index_mmap(new_map, file_size);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
348 } else {
15212
b7ac3897f3fd lib-index: dovecot.index file is no longer overwritten, so it doesn't need to be locked.
Timo Sirainen <tss@iki.fi>
parents: 14231
diff changeset
349 ret = mail_index_read_map(new_map, file_size);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
350 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
351 if (ret == 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
352 /* the index files are unusable */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
353 unusable = TRUE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
354 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
355
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
356 for (try = 0; ret > 0; try++) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
357 /* make sure the header is ok before using this mapping */
18627
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
358 ret = mail_index_map_check_header(new_map, &error);
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
359 if (ret < 0) {
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
360 mail_index_set_error(index,
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
361 "Corrupted index file %s: %s",
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
362 index->filepath, error);
69630e6048fd lib-index: If header is corrupted after syncing, log the reason why.
Timo Sirainen <tss@iki.fi>
parents: 18137
diff changeset
363 }
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
364 if (ret > 0) T_BEGIN {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
365 if (mail_index_map_parse_extensions(new_map) < 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
366 ret = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
367 else if (mail_index_map_parse_keywords(new_map) < 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
368 ret = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
369 } T_END;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
370 if (ret != 0 || try == 2) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
371 if (ret < 0) {
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
372 *reason_r = "Corrupted index file";
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
373 unusable = TRUE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
374 ret = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
375 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
376 break;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
377 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
378
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
379 /* fsck and try again */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
380 old_map = index->map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
381 index->map = new_map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
382 if (mail_index_fsck(index) < 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
383 ret = -1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384 break;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
386
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
387 /* fsck replaced the map */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
388 new_map = index->map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
389 index->map = old_map;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 if (ret <= 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
392 mail_index_unmap(&new_map);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393 return ret < 0 ? -1 : (unusable ? 0 : 1);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
394 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 i_assert(new_map->rec_map->records != NULL);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
396
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
397 index->last_read_log_file_seq = new_map->hdr.log_file_seq;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
398 index->last_read_log_file_tail_offset =
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
399 new_map->hdr.log_file_tail_offset;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
401 mail_index_unmap(&index->map);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
402 index->map = new_map;
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
403 *reason_r = "Index mapped";
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
404 return 1;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
406
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
407 int mail_index_map(struct mail_index *index,
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
408 enum mail_index_sync_handler_type type)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
409 {
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
410 const char *reason;
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
411 int ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
412
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413 i_assert(!index->mapping);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
414
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
415 index->mapping = TRUE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
416
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
417 if (index->map == NULL)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
418 index->map = mail_index_map_alloc(index);
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
419
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
420 /* first try updating the existing mapping from transaction log. */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
421 if (index->initial_mapped) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
422 /* we're not creating/opening the index.
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
423 sync this as a view from transaction log. */
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
424 ret = mail_index_sync_map(&index->map, type, FALSE, "initial mapping");
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
425 } else {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
426 ret = 0;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
427 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
428
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
429 if (ret == 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
430 /* try to open and read the latest index. if it fails, we'll
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
431 fallback to updating the existing mapping from transaction
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
432 logs (which we'll also do even if the reopening succeeds).
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
433 if index files are unusable (e.g. major version change)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
434 don't even try to use the transaction log. */
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
435 ret = mail_index_map_latest_file(index, &reason);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
436 if (ret > 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
437 /* if we're creating the index file, we don't have any
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
438 logs yet */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
439 if (index->log->head != NULL && index->indexid != 0) {
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
440 /* and update the map with the latest changes
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
441 from transaction log */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
442 ret = mail_index_sync_map(&index->map, type,
21087
3b909cd1264b lib-index: Improve error messages when transaction log is unexpectedly lost
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20281
diff changeset
443 TRUE, reason);
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
444 }
21221
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
445 if (ret == 0) {
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
446 /* we fsck'd the index. try opening again. */
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
447 ret = mail_index_map_latest_file(index, &reason);
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
448 if (ret > 0 && index->indexid != 0) {
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
449 ret = mail_index_sync_map(&index->map,
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
450 type, TRUE, reason);
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
451 }
11110656c294 lib-index: If index open fails with fsck, retry opening once.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21192
diff changeset
452 }
12100
39fef730dec3 lib-index: readonly status was checked wrong when deleting corrupted index files.
Timo Sirainen <tss@iki.fi>
parents: 11310
diff changeset
453 } else if (ret == 0 && !index->readonly) {
9332
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
454 /* make sure we don't try to open the file again */
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
455 if (unlink(index->filepath) < 0 && errno != ENOENT)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
456 mail_index_set_syscall_error(index, "unlink()");
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
457 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
458 }
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460 if (ret >= 0)
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
461 index->initial_mapped = TRUE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
462 index->mapping = FALSE;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463 return ret;
e55de8b34144 Moved some code from mail-index-map.c to mail-index-map-read.c
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
464 }