dovecot-2.1: lib-index: Added mail_index_set_ext_init_data() for...

dovecot at dovecot.org dovecot at dovecot.org
Thu Feb 9 00:41:49 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/2ab26bb55346
changeset: 14079:2ab26bb55346
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Feb 09 00:39:52 2012 +0200
description:
lib-index: Added mail_index_set_ext_init_data() for adding data to index on creation.
This can be used to avoid race conditions on mailbox creation for mailbox
formats that require this (sdbox).

diffstat:

 src/lib-index/mail-index-private.h        |   3 +
 src/lib-index/mail-index.c                |  18 ++++++++++
 src/lib-index/mail-index.h                |   4 ++
 src/lib-index/mail-transaction-log-file.c |  54 +++++++++++++++++++++++++++++-
 4 files changed, 77 insertions(+), 2 deletions(-)

diffs (155 lines):

diff -r f6102f0af71d -r 2ab26bb55346 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Thu Feb 09 00:38:30 2012 +0200
+++ b/src/lib-index/mail-index-private.h	Thu Feb 09 00:39:52 2012 +0200
@@ -181,6 +181,9 @@
 	pool_t extension_pool;
 	ARRAY_DEFINE(extensions, struct mail_index_registered_ext);
 
+	uint32_t ext_hdr_init_id;
+	void *ext_hdr_init_data;
+
 	ARRAY_DEFINE(sync_lost_handlers, mail_index_sync_lost_handler_t *);
 
 	char *filepath;
diff -r f6102f0af71d -r 2ab26bb55346 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c	Thu Feb 09 00:38:30 2012 +0200
+++ b/src/lib-index/mail-index.c	Thu Feb 09 00:39:52 2012 +0200
@@ -77,6 +77,7 @@
 	array_free(&index->keywords);
 	array_free(&index->module_contexts);
 
+	i_free(index->ext_hdr_init_data);
 	i_free(index->gid_origin);
 	i_free(index->error);
 	i_free(index->dir);
@@ -110,6 +111,23 @@
 	index->max_lock_timeout_secs = max_timeout_secs;
 }
 
+void mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
+				  const void *data, size_t size)
+{
+	const struct mail_index_registered_ext *rext;
+
+	i_assert(index->ext_hdr_init_data == NULL ||
+		 index->ext_hdr_init_id == ext_id);
+
+	rext = array_idx(&index->extensions, ext_id);
+	i_assert(rext->hdr_size == size);
+
+	index->ext_hdr_init_id = ext_id;
+	i_free(index->ext_hdr_init_data);
+	index->ext_hdr_init_data = i_malloc(size);
+	memcpy(index->ext_hdr_init_data, data, size);
+}
+
 uint32_t mail_index_ext_register(struct mail_index *index, const char *name,
 				 uint32_t default_hdr_size,
 				 uint16_t default_record_size,
diff -r f6102f0af71d -r 2ab26bb55346 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Thu Feb 09 00:38:30 2012 +0200
+++ b/src/lib-index/mail-index.h	Thu Feb 09 00:39:52 2012 +0200
@@ -217,6 +217,10 @@
 void mail_index_set_lock_method(struct mail_index *index,
 				enum file_lock_method lock_method,
 				unsigned int max_timeout_secs);
+/* When creating a new index file or reseting an existing one, add the given
+   extension header data immediately to it. */
+void mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
+				  const void *data, size_t size);
 
 /* Open index. Returns 1 if ok, 0 if index doesn't exist and CREATE flags
    wasn't given, -1 if error. */
diff -r f6102f0af71d -r 2ab26bb55346 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Thu Feb 09 00:38:30 2012 +0200
+++ b/src/lib-index/mail-transaction-log-file.c	Thu Feb 09 00:39:52 2012 +0200
@@ -1,8 +1,8 @@
 /* Copyright (c) 2003-2011 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "array.h"
 #include "ioloop.h"
-#include "buffer.h"
 #include "file-dotlock.h"
 #include "nfs-workarounds.h"
 #include "read-full.h"
@@ -587,6 +587,45 @@
 	return FALSE;
 }
 
+static void log_write_ext_hdr_init_data(struct mail_index *index, buffer_t *buf)
+{
+	const struct mail_index_registered_ext *rext;
+	struct mail_transaction_header *hdr;
+	struct mail_transaction_ext_intro *intro;
+	struct mail_transaction_ext_hdr_update *ext_hdr;
+	unsigned int hdr_offset;
+
+	rext = array_idx(&index->extensions, index->ext_hdr_init_id);
+
+	/* introduce the extension */
+	hdr_offset = buf->used;
+	hdr = buffer_append_space_unsafe(buf, sizeof(*hdr));
+	hdr->type = MAIL_TRANSACTION_EXT_INTRO;
+
+	intro = buffer_append_space_unsafe(buf, sizeof(*intro));
+	intro->ext_id = (uint32_t)-1;
+	intro->hdr_size = rext->hdr_size;
+	intro->record_size = rext->record_size;
+	intro->record_align = rext->record_align;
+	intro->name_size = strlen(rext->name);
+	buffer_append(buf, rext->name, intro->name_size);
+
+	hdr = buffer_get_space_unsafe(buf, hdr_offset, sizeof(*hdr));
+	hdr->size = mail_index_uint32_to_offset(buf->used - hdr_offset);
+
+	/* add the extension header data */
+	hdr_offset = buf->used;
+	hdr = buffer_append_space_unsafe(buf, sizeof(*hdr));
+	hdr->type = MAIL_TRANSACTION_EXT_HDR_UPDATE;
+
+	ext_hdr = buffer_append_space_unsafe(buf, sizeof(*ext_hdr));
+	ext_hdr->size = rext->hdr_size;
+	buffer_append(buf, index->ext_hdr_init_data, rext->hdr_size);
+
+	hdr = buffer_get_space_unsafe(buf, hdr_offset, sizeof(*hdr));
+	hdr->size = mail_index_uint32_to_offset(buf->used - hdr_offset);
+}
+
 static int
 mail_transaction_log_file_create2(struct mail_transaction_log_file *file,
 				  int new_fd, bool reset,
@@ -595,6 +634,7 @@
 	struct mail_index *index = file->log->index;
 	struct stat st;
 	const char *path2;
+	buffer_t *writebuf;
 	int fd, ret;
 	bool rename_existing;
 
@@ -651,6 +691,11 @@
 		rename_existing = FALSE;
 	}
 
+	if (index->fd == -1 && !rename_existing) {
+		/* creating the initial index */
+		reset = TRUE;
+	}
+
 	if (mail_transaction_log_init_hdr(file->log, &file->hdr) < 0)
 		return -1;
 
@@ -662,7 +707,12 @@
 		file->hdr.prev_file_offset = 0;
 	}
 
-	if (write_full(new_fd, &file->hdr, sizeof(file->hdr)) < 0)
+	writebuf = buffer_create_dynamic(pool_datastack_create(), 128);
+	buffer_append(writebuf, &file->hdr, sizeof(file->hdr));
+
+	if (index->ext_hdr_init_data != NULL && reset)
+		log_write_ext_hdr_init_data(index, writebuf);
+	if (write_full(new_fd, writebuf->data, writebuf->used) < 0)
 		return log_file_set_syscall_error(file, "write_full()");
 
 	if (file->log->index->fsync_mode == FSYNC_MODE_ALWAYS) {


More information about the dovecot-cvs mailing list