Mercurial > dovecot > core-2.2
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 |
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 | 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 } |