mail-index-map.c revision 90a989e4f8bcb4fb86af32cbae577402e3f92b1a
0N/A/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */ 928N/A /* try to use the existing pool's size for initial_count so 928N/A we don't grow it unneededly */ /* Update index ext_id -> map ext_id mapping. Fill non-used ext_ids with (uint32_t)-1 */ /* Extension header contains: - struct mail_index_ext_header - name (not 0-terminated) - 64bit alignment padding - extension header contents - 64bit alignment padding /* we allow only plain ASCII names, so this extension /* finally make sure that the hdr_size is small enough. do this last so that we could return a usable name. */ /* if we get here from extension introduction, record_offset=0 and hdr->record_size hasn't been updated yet */ "outside record size (%u+%u > %u)",
"as required by extension",
/* extension headers always start from 64bit offsets, so if base header doesn't happen to be 64bit aligned we'll skip some bytes */ /* nothing to do, skip allocatations and all */ "Header extension #%d (%s) goes outside header",
"Broken extension #%d (%s): %s",
"Duplicate header extension %s",
/* Extension header contains: - struct mail_index_keyword_header - struct mail_index_keyword_header_rec * keywords_count - const char names[] * keywords_count /* Keywords can only be added into same mapping. Removing requires a new mapping (recreating the index file) */ /* make sure the header is valid */ "Keywords removed unexpectedly",
"keywords_count larger than header size",
"name_offset points outside allocated header",
"Keyword header doesn't end with NUL",
/* create file -> index mapping */ /* Check that existing headers are still the same. It's behind DEBUG since it's pretty useless waste of CPU normally. */ "Keywords changed unexpectedly",
/* Register the newly seen keywords */ "Empty keyword name in header",
/* major version change - handle silently(?) */ /* we've already complained about it */ /* architecture change */ "CPU architecture changed",
"Corrupted header sizes (base %u, full %u)",
"indexid changed: %u -> %u",
/* following some extra checks that only take a bit of CPU */ /* upgrade silently from v1.0 */ /* pre-v1.1.rc6: make sure the \Recent flags are gone */ /* last message's UID must be smaller than next_uid. also make sure it's not zero. */ /* header smaller than ours, make a copy so our newer headers won't have garbage in them */ /* FIXME: backwards compatibility, remove later. In case this index is accessed with Dovecot v1.0, avoid recent message counter errors. */ /* too large file to map into memory */ /* major version change - handle silently */ /* Can't use this file */ "messages_count too large (%u > %u)",
/* try to read the whole header, but it's not necessarily an error to read less since the older versions of the index format could be smaller. Request reading up to buf_size, but accept if we only got /* major version change - handle silently */ /* Can't use this file */ /* place the base header into memory. */ /* @UNSAFE: read the rest of the header into memory */ /* header read, read the records now. */ "messages_count too large (%u > %u)",
/* a new index file was renamed over this one. */ "Corrupted index file %s: File too small",
/* notify all "sync lost" handlers */ for (i = 0; i <
count; i++)
/* fstat() below failed */ /* ESTALE - reopen index file */ /* a bit kludgy way to do this, but it initializes everything /* returns -1 = error, 0 = index files are unusable, 1 = index files are usable or at least repairable */ /* the index file is lost/broken. let's hope that we can build it from the transaction log. */ /* the index file is still open, lock it */ /* mmaping seems to be slower than just reading the file, so even if mmap isn't disabled don't use it unless the file is large enough */ /* the index files are unusable */ /* make sure the header is ok before using this mapping */ /* fsck replaced the map */ /* first try updating the existing mapping from transaction log. */ sync this as a view from transaction log. */ /* try to open and read the latest index. if it fails, we'll fallback to updating the existing mapping from transaction logs (which we'll also do even if the reopening succeeds). if index files are unusable (e.g. major version change) don't even try to use the transaction log. */ /* make sure we don't try to open the file again */ /* if we're creating the index file, we don't have any /* and update the map with the latest changes for (i = 0; i <
count; i++) {
if (i == 0 &&
count ==
1) {
/* if the map is ever written back to disk, we need to keep track of /* use src->hdr copy directly, because if we got here from syncing it has the latest changes. */ /* fix the name pointers to use our own pool */ for (i = 0; i <
count; i++) {