[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.44,
1.45 mail-index-private.h, 1.57, 1.58 mail-index-sync-ext.c,
1.12, 1.13 mail-index-sync-keywords.c, 1.7,
1.8 mail-index-sync-update.c, 1.87, 1.88
cras at dovecot.org
cras at dovecot.org
Mon Jan 2 14:22:43 EET 2006
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv28235
Modified Files:
mail-index-lock.c mail-index-private.h mail-index-sync-ext.c
mail-index-sync-keywords.c mail-index-sync-update.c
Log Message:
Don't rewrite index file every time with mmap_disable=yes.
Index: mail-index-lock.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- mail-index-lock.c 3 Oct 2005 21:23:23 -0000 1.44
+++ mail-index-lock.c 2 Jan 2006 12:22:41 -0000 1.45
@@ -241,6 +241,8 @@
static int mail_index_copy(struct mail_index *index)
{
+ struct mail_index_map *map = index->map;
+ unsigned int base_size;
const char *path;
int ret, fd;
@@ -251,22 +253,16 @@
return -1;
/* write base header */
- ret = write_full(fd, &index->map->hdr,
- index->map->hdr.base_header_size);
+ base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
+ ret = write_full(fd, &map->hdr, base_size);
if (ret == 0) {
/* write extended headers */
- const struct mail_index_header *hdr;
- const void *hdr_ext;
-
- hdr = index->map->hdr_base;
- hdr_ext = CONST_PTR_OFFSET(hdr, hdr->base_header_size);
- ret = write_full(fd, hdr_ext, hdr->header_size -
- hdr->base_header_size);
+ ret = write_full(fd, CONST_PTR_OFFSET(map->hdr_base, base_size),
+ map->hdr.header_size - base_size);
}
- if (ret < 0 || write_full(fd, index->map->records,
- index->map->records_count *
- index->map->hdr.record_size) < 0) {
+ if (ret < 0 || write_full(fd, map->records, map->records_count *
+ map->hdr.record_size) < 0) {
mail_index_file_set_syscall_error(index, path, "write_full()");
(void)close(fd);
(void)unlink(path);
@@ -366,14 +362,45 @@
return 0;
}
-static void mail_index_excl_unlock_finish(struct mail_index *index)
+static int mail_index_write_map_over(struct mail_index *index)
+{
+ struct mail_index_map *map = index->map;
+ unsigned int base_size;
+
+ /* write records. */
+ if (map->write_seq_first != 0) {
+ uoff_t offset = map->hdr.header_size +
+ (map->write_seq_first-1) * map->hdr.record_size;
+
+ if (pwrite_full(index->fd, map->records,
+ (map->write_seq_last -
+ map->write_seq_first + 1) *
+ map->hdr.record_size, offset) < 0)
+ return -1;
+ }
+
+ /* write base header */
+ base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
+ if (pwrite_full(index->fd, &map->hdr, base_size, 0) < 0)
+ return -1;
+
+ /* write extended headers */
+ if (pwrite_full(index->fd, CONST_PTR_OFFSET(map->hdr_base, base_size),
+ map->hdr.header_size - base_size, base_size) < 0)
+ return -1;
+ return 0;
+}
+
+static void mail_index_write_map(struct mail_index *index)
{
+ struct mail_index_map *map = index->map;
int fd;
- if (index->map != NULL && index->map->write_to_disk) {
+ if (map->write_atomic || index->copy_lock_path != NULL ||
+ index->fd == -1) {
+ /* write by recreating the index */
i_assert(index->log_locked);
- index->map->write_to_disk = FALSE;
if (index->copy_lock_path != NULL) {
/* new mapping replaces the old */
(void)unlink(index->copy_lock_path);
@@ -388,8 +415,23 @@
else
(void)close(fd);
}
+ } else {
+ /* write the modified parts. header is small enough to be
+ always written, write_seq_* specifies the record range. */
+ if (mail_index_write_map_over(index) < 0)
+ mail_index_set_inconsistent(index);
}
+ map->write_to_disk = FALSE;
+ map->write_atomic = FALSE;
+ map->write_seq_first = map->write_seq_last = 0;
+}
+
+static void mail_index_excl_unlock_finish(struct mail_index *index)
+{
+ if (index->map != NULL && index->map->write_to_disk)
+ mail_index_write_map(index);
+
if (index->shared_lock_count > 0 &&
index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
/* leave ourself shared locked. */
Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- mail-index-private.h 24 Sep 2005 10:10:56 -0000 1.57
+++ mail-index-private.h 2 Jan 2006 12:22:41 -0000 1.58
@@ -94,7 +94,13 @@
array_t ARRAY_DEFINE(keyword_idx_map, unsigned int); /* file -> index */
+ /* If write_to_disk=TRUE and write_atomic=FALSE, these sequences
+ specify the range that needs to be written. Header should always
+ be rewritten. */
+ uint32_t write_seq_first, write_seq_last;
+
unsigned int write_to_disk:1;
+ unsigned int write_atomic:1; /* copy to new file and rename() */
};
struct mail_index {
Index: mail-index-sync-ext.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-ext.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- mail-index-sync-ext.c 28 Oct 2005 14:10:13 -0000 1.12
+++ mail-index-sync-ext.c 2 Jan 2006 12:22:41 -0000 1.13
@@ -340,6 +340,10 @@
if (old_record_size != u->record_size) {
map = sync_ext_reorder(map, ext_id, old_record_size);
mail_index_sync_replace_map(ctx, map);
+ } else if (modified) {
+ /* header size changed. recreate index file. */
+ map = mail_index_map_clone(map, map->hdr.record_size);
+ mail_index_sync_replace_map(ctx, map);
}
}
@@ -477,6 +481,8 @@
memset(PTR_OFFSET(rec, ext->record_offset), 0,
ext->record_size);
}
+ map->write_seq_first = 1;
+ map->write_seq_last = view->map->records_count;
ext_hdr = get_ext_header(map, ext);
ext_hdr->reset_id = u->new_reset_id;
@@ -545,6 +551,11 @@
return ret;
}
+ if (view->map->write_seq_first == 0 || view->map->write_seq_first > seq)
+ view->map->write_seq_first = seq;
+ if (view->map->write_seq_last < seq)
+ view->map->write_seq_last = seq;
+
/* @UNSAFE */
memcpy(old_data, u + 1, ext->record_size);
return 1;
Index: mail-index-sync-keywords.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-keywords.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-index-sync-keywords.c 25 Aug 2005 17:17:59 -0000 1.7
+++ mail-index-sync-keywords.c 2 Jan 2006 12:22:41 -0000 1.8
@@ -210,6 +210,12 @@
if (seq1 == 0)
return 1;
+ if (view->map->write_seq_first == 0 ||
+ view->map->write_seq_first > seq1)
+ view->map->write_seq_first = seq1;
+ if (view->map->write_seq_last < seq2)
+ view->map->write_seq_last = seq2;
+
data_offset = keyword_idx / CHAR_BIT;
data_mask = 1 << (keyword_idx % CHAR_BIT);
@@ -345,6 +351,11 @@
if (seq1 == 0)
continue;
+ if (map->write_seq_first == 0 || map->write_seq_first > seq1)
+ map->write_seq_first = seq1;
+ if (map->write_seq_last < seq2)
+ map->write_seq_last = seq2;
+
for (seq1--; seq1 < seq2; seq1++) {
rec = MAIL_INDEX_MAP_IDX(map, seq1);
memset(PTR_OFFSET(rec, ext->record_offset),
Index: mail-index-sync-update.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- mail-index-sync-update.c 27 Aug 2005 12:40:53 -0000 1.87
+++ mail-index-sync-update.c 2 Jan 2006 12:22:41 -0000 1.88
@@ -27,8 +27,10 @@
view->index->map = map;
view->index->hdr = &map->hdr;
- if (ctx->type == MAIL_INDEX_SYNC_HANDLER_INDEX)
+ if (ctx->type == MAIL_INDEX_SYNC_HANDLER_INDEX) {
map->write_to_disk = TRUE;
+ map->write_atomic = TRUE;
+ }
}
static void
@@ -121,6 +123,9 @@
}
i_assert(MAIL_INDEX_MAP_IS_IN_MEMORY(map));
+ /* we want atomic rename()ing */
+ map->write_atomic = TRUE;
+
if (mail_index_lookup_uid_range(view, e->uid1, e->uid2,
&seq1, &seq2) < 0)
return -1;
@@ -210,6 +215,10 @@
map->records_count++;
view->hdr.messages_count++;
+ if (map->write_seq_first == 0)
+ map->write_seq_first = map->hdr.messages_count;
+ map->write_seq_last = map->hdr.messages_count;
+
if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0)
map->hdr.flags |= MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
@@ -241,6 +250,12 @@
if (seq1 == 0)
return 1;
+ if (view->map->write_seq_first == 0 ||
+ view->map->write_seq_first > seq1)
+ view->map->write_seq_first = seq1;
+ if (view->map->write_seq_last < seq2)
+ view->map->write_seq_last = seq2;
+
hdr = &view->map->hdr;
if ((u->add_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0)
hdr->flags |= MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
@@ -725,13 +740,16 @@
}
if (!MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
+ unsigned int base_size,
+
+ base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
map->mmap_used_size = index->hdr->header_size +
map->records_count * map->hdr.record_size;
- memcpy(map->mmap_base, &map->hdr, sizeof(map->hdr));
- memcpy(PTR_OFFSET(map->mmap_base, sizeof(map->hdr)),
- PTR_OFFSET(map->hdr_base, sizeof(map->hdr)),
- map->hdr.header_size - sizeof(map->hdr));
+ memcpy(map->mmap_base, &map->hdr, base_size);
+ memcpy(PTR_OFFSET(map->mmap_base, base_size),
+ PTR_OFFSET(map->hdr_base, base_size),
+ map->hdr.header_size - base_size);
if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
mail_index_set_syscall_error(index, "msync()");
ret = -1;
More information about the dovecot-cvs
mailing list