mail-index-map-read.c revision 2988b4cbf3540a0c02a9ddf185cafec5938c0cac
/* Copyright (c) 2003-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "nfs-workarounds.h"
#include "mmap-util.h"
#include "read-full.h"
#include "mail-index-private.h"
#include "mail-index-sync-private.h"
#include "mail-transaction-log-private.h"
const struct mail_index_header *hdr)
{
/* header smaller than ours, make a copy so our newer headers
won't have garbage in them */
} else {
}
/* FIXME: backwards compatibility, remove later. In case this index is
accessed with Dovecot v1.0, avoid recent message counter errors. */
}
{
const struct mail_index_header *hdr;
const char *error;
if (file_size > SSIZE_T_MAX) {
/* too large file to map into memory */
return -1;
}
return -1;
}
/* major version change - handle silently */
return 0;
}
return 0;
}
/* Can't use this file */
return -1;
}
else {
"messages_count too large (%u > %u)",
}
return 1;
}
{
int ret;
/* 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
the header. */
pos = 0;
do {
if (ret > 0)
return ret;
}
static int
{
const struct mail_index_header *hdr;
unsigned char read_buf[IO_BLOCK_SIZE];
const char *error;
const void *buf;
unsigned int records_count = 0, extra;
/* major version change - handle silently */
return 0;
}
/* Can't use this file */
return -1;
}
/* place the base header into memory. */
/* @UNSAFE: read the rest of the header into memory */
hdr->header_size -
pos);
}
}
if (ret > 0) {
/* header read, read the records now. */
(hdr->record_size != 0 &&
"messages_count too large (%u > %u)",
}
}
/* @UNSAFE */
extra = 0;
else {
extra);
}
if (records_size > extra) {
records_size - extra);
}
}
if (ret < 0) {
/* a new index file was renamed over this one. */
return 0;
}
return -1;
}
if (ret == 0) {
"Corrupted index file %s: File too small",
return 0;
}
return 1;
}
{
mail_index_sync_lost_handler_t *const *handlerp;
unsigned int i;
int ret;
/* notify all "sync lost" handlers */
for (i = 0;; i++) {
/* fstat() below failed */
ret = 0;
} else {
}
break;
/* ESTALE - reopen index file */
if (ret <= 0) {
if (ret == 0) {
/* the file was lost */
}
return -1;
}
else {
if (!ESTALE_FSTAT(errno)) {
return -1;
}
}
}
return ret;
}
/* returns -1 = error, 0 = index files are unusable,
1 = index files are usable or at least repairable */
{
const char *error;
if (ret <= 0) {
if (ret < 0)
return -1;
build it from the transaction log. */
return 1;
}
else {
if (!ESTALE_FSTAT(errno)) {
return -1;
}
}
/* 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 */
if (use_mmap) {
} else {
}
if (ret == 0) {
/* the index files are unusable */
}
/* make sure the header is ok before using this mapping */
if (ret < 0) {
"Corrupted index file %s: %s",
}
if (mail_index_map_parse_extensions(new_map) < 0)
ret = 0;
else if (mail_index_map_parse_keywords(new_map) < 0)
ret = 0;
} T_END;
if (ret < 0) {
ret = 0;
}
break;
}
/* fsck and try again */
if (mail_index_fsck(index) < 0) {
ret = -1;
break;
}
/* fsck replaced the map */
}
if (ret <= 0) {
}
return 1;
}
{
int ret;
/* first try updating the existing mapping from transaction log. */
if (index->initial_mapped) {
sync this as a view from transaction log. */
} else {
ret = 0;
}
if (ret == 0) {
/* 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. */
if (ret > 0) {
/* if we're creating the index file, we don't have any
logs yet */
/* and update the map with the latest changes
from transaction log */
TRUE);
}
/* make sure we don't try to open the file again */
}
}
if (ret >= 0)
return ret;
}