mail-index.c revision 0dc2c6fc020c80d24f54a1a8e534613dba3d06b1
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (C) 2002 Timo Sirainen */
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen unsigned int extra;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (index->mmap_full_length < sizeof(MailIndexHeader)) {
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainen extra = (index->mmap_full_length - sizeof(MailIndexHeader)) %
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen /* partial write or corrupted -
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen truncate the file to valid length */
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen (void)ftruncate(index->fd, (off_t)index->mmap_full_length);
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen /* keep the header set even if we fail, so we can update the flags */
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (hdr->used_file_size > index->mmap_full_length) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index_set_corrupted(index, "used_file_size larger than real "
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if ((hdr->used_file_size - sizeof(MailIndexHeader)) %
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen sizeof(MailIndexRecord) != 0) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index_set_corrupted(index, "Invalid used_file_size in header "
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (hdr->messages_count < hdr->seen_messages_count) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index_set_corrupted(index, "Invalid seen messages count "
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (hdr->messages_count < hdr->deleted_messages_count) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index_set_corrupted(index, "Invalid deleted messages count "
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index->mmap_used_length = hdr->used_file_size;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index->header = (MailIndexHeader *) index->mmap_base;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen /* make sure file size hasn't changed */
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (index->header->sync_id == index->sync_id) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen index->mmap_used_length = index->header->used_file_size;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (index->mmap_used_length > index->mmap_full_length) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen "updating sync_id");
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen return index_set_syscall_error(index, "msync()");
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen if (munmap(index->mmap_base, index->mmap_full_length) < 0)
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen return index_set_syscall_error(index, "munmap()");
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen index->mmap_base = mmap_rw_file(index->fd, &index->mmap_full_length);
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen if (munmap_anon(index->mmap_base, index->mmap_full_length) < 0)
6a33ecc05e60b511c1ae176ef113546e1012c18fTimo Sirainen index_set_syscall_error(index, "munmap_anon()");
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen if (munmap(index->mmap_base, index->mmap_full_length) < 0)
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi unsigned int i;
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi for (i = 0; i < sizeof(fsync_fds)/sizeof(fsync_fds[0]); i++)
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi if (!mail_index_data_sync_file(index->data, &fsync_fds[0]))
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi if (msync(index->mmap_base, index->mmap_used_length, MS_SYNC) < 0)
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi if (!mail_tree_sync_file(index->tree, &fsync_fds[1]))
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi if (!mail_modifylog_sync_file(index->modifylog, &fsync_fds[2]))
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi for (i = 0; i < sizeof(fsync_fds)/sizeof(fsync_fds[0]); i++) {
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi if (fsync_fds[i] != -1 && fdatasync(fsync_fds[i]) < 0)
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi index_set_error(index, "fdatasync(%u) failed: %m", i);
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi return index_set_syscall_error(index, "fdatasync()");
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomistatic void mail_index_update_timestamp(MailIndex *index)
c9dd53f7180a78668cbc1e6eb34d5b1722beccb9Aki Tuomi /* keep index's modify stamp same as the sync file's stamp */
return TRUE;
int failed;
#ifdef DEBUG
if (failed)
#ifdef DEBUG
return !failed;
return TRUE;
int try_lock)
return FALSE;
if (try_lock) {
if (ret < 0)
if (ret <= 0)
return FALSE;
DEFAULT_LOCK_TIMEOUT) <= 0) {
return FALSE;
return FALSE;
return FALSE;
DEFAULT_LOCK_TIMEOUT) <= 0)
return FALSE;
return FALSE;
return TRUE;
int try_lock)
int keep_fsck;
return TRUE;
index);
return TRUE;
MS_SYNC) < 0) {
unsigned int max_records;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
const char *format;
unsigned int idx;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return rec;
return NULL;
return rec;
return NULL;
unsigned int first_uid,
unsigned int last_uid,
unsigned int *seq_r)
unsigned int idx;
return NULL;
return NULL;
return NULL;
return rec;
return NULL;
return NULL;
*size = 0;
return NULL;
*size = 0;
return NULL;
*size = 0;
return NULL;
switch (field) {
case DATA_HDR_INTERNAL_DATE:
case DATA_HDR_VIRTUAL_SIZE:
case DATA_HDR_HEADER_SIZE:
case DATA_HDR_BODY_SIZE:
*size = 0;
return NULL;
return *date;
sizeof(MailIndexHeader)) +
rec++;
sizeof(MailIndexRecord);
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
int external_change)
unsigned int grow_count;
void *base;
return FALSE;
return TRUE;
return NULL;
return rec;
return TRUE;