[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