Mercurial > dovecot > core-2.2
diff src/lib-index/mail-index.c @ 29:e9375147c0cb HEAD
Added write_full() which is a simple wrapper around write() meant for
writing into files.
When there's too much deleted data in index files, they're now compressed
when the index is being opened.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 26 Aug 2002 02:46:59 +0300 |
parents | 55e09f36d23d |
children | 33e86ee7d167 |
line wrap: on
line diff
--- a/src/lib-index/mail-index.c Mon Aug 26 02:22:41 2002 +0300 +++ b/src/lib-index/mail-index.c Mon Aug 26 02:46:59 2002 +0300 @@ -4,6 +4,7 @@ #include "ioloop.h" #include "hostpid.h" #include "mmap-util.h" +#include "write-full.h" #include "mail-index.h" #include "mail-index-data.h" #include "mail-index-util.h" @@ -149,6 +150,24 @@ return !failed; } +int mail_index_fmsync(MailIndex *index, size_t size) +{ + i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE); + + if (msync(index->mmap_base, size, MS_SYNC) == -1) { + index_set_error(index, "msync() failed for %s: %m", + index->filepath); + return FALSE; + } + if (fsync(index->fd) == -1) { + index_set_error(index, "fsync() failed for %s: %m", + index->filepath); + return FALSE; + } + + return TRUE; +} + int mail_index_rebuild_all(MailIndex *index) { if (!index->rebuild(index)) @@ -309,16 +328,7 @@ when the lock is released, the FSCK flag will also be removed. */ index->header->flags |= MAIL_INDEX_FLAG_FSCK; - if (msync(index->mmap_base, sizeof(MailIndexHeader), - MS_SYNC) == -1) { - index_set_error(index, "msync() failed for %s: %m", - index->filepath); - (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK); - return FALSE; - } - if (fsync(index->fd) == -1) { - index_set_error(index, "fsync() failed for %s: %m", - index->filepath); + if (!mail_index_fmsync(index, sizeof(MailIndexHeader))) { (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK); return FALSE; } @@ -515,12 +525,31 @@ break; } + if (hdr.flags & MAIL_INDEX_FLAG_COMPRESS) { + /* remove deleted blocks from index file */ + if (!mail_index_compress(index)) + break; + } + + if (hdr.flags & MAIL_INDEX_FLAG_REBUILD_HASH) { + if (!mail_hash_rebuild(index->hash)) + break; + } + if (hdr.flags & MAIL_INDEX_FLAG_CACHE_FIELDS) { /* need to update cached fields */ if (!mail_index_update_cache(index)) break; } + if (hdr.flags & MAIL_INDEX_FLAG_COMPRESS_DATA) { + /* remove unused space from index data file. + keep after cache_fields which may move data + and create unused space.. */ + if (!mail_index_compress_data(index)) + break; + } + if (!index->sync(index)) break; if (!mail_index_open_init(index, update_recent, &hdr)) @@ -582,7 +611,7 @@ mail_index_init_header(&hdr); /* write header */ - if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { + if (write_full(fd, &hdr, sizeof(hdr)) < 0) { index_set_error(index, "Error writing to temp index %s: %m", path); (void)close(fd); @@ -728,7 +757,7 @@ unsigned int lookup_seq) { MailIndexHeader *hdr; - MailIndexRecord *rec, *last_rec; + MailIndexRecord *rec, *end_rec; unsigned int seq; off_t seekpos; @@ -764,9 +793,6 @@ } /* we need to walk through the index to get to wanted position */ - last_rec = rec + (index->mmap_length-sizeof(MailIndexHeader)) / - sizeof(MailIndexRecord); - if (lookup_seq > index->last_lookup_seq && index->last_lookup != NULL) { /* we want to lookup data after last lookup - this helps us some */ @@ -781,17 +807,11 @@ rec += seq-1 + hdr->first_hole_records; } - if (rec == last_rec) - return NULL; - - while (seq < lookup_seq || rec->uid == 0) { + end_rec = (MailIndexRecord *) ((char *) index->mmap_base + + index->mmap_length); + while (seq < lookup_seq && rec < end_rec) { if (rec->uid != 0) seq++; - - if (rec == last_rec) { - /* out of range */ - return NULL; - } rec++; } @@ -1119,8 +1139,7 @@ return FALSE; } - if (write(index->fd, *rec, sizeof(MailIndexRecord)) != - sizeof(MailIndexRecord)) { + if (write_full(index->fd, *rec, sizeof(MailIndexRecord)) < 0) { index_set_error(index, "Error appending to file %s: %m", index->filepath); return FALSE;