dovecot-1.1: Added support for dotlocks.

dovecot at dovecot.org dovecot at dovecot.org
Fri Mar 7 08:15:38 EET 2008


details:   http://hg.dovecot.org/dovecot-1.1/rev/55712d36224b
changeset: 7371:55712d36224b
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Mar 07 08:15:35 2008 +0200
description:
Added support for dotlocks.

diffstat:

4 files changed, 114 insertions(+), 42 deletions(-)
src/plugins/fts-squat/squat-trie-private.h |    5 +
src/plugins/fts-squat/squat-trie.c         |   85 ++++++++++++++++++++--------
src/plugins/fts-squat/squat-trie.h         |    9 ++
src/plugins/fts-squat/squat-uidlist.c      |   57 +++++++++++++-----

diffs (truncated from 384 to 300 lines):

diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie-private.h
--- a/src/plugins/fts-squat/squat-trie-private.h	Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie-private.h	Fri Mar 07 08:15:35 2008 +0200
@@ -1,10 +1,12 @@
 #ifndef SQUAT_TRIE_PRIVATE_H
 #define SQUAT_TRIE_PRIVATE_H
 
+#include "file-dotlock.h"
 #include "squat-trie.h"
 
 #define SQUAT_TRIE_VERSION 2
 #define SQUAT_TRIE_LOCK_TIMEOUT 60
+#define SQUAT_TRIE_DOTLOCK_STALE_TIMEOUT (15*60)
 
 struct squat_file_header {
 	uint8_t version;
@@ -114,12 +116,14 @@ struct squat_trie {
 	size_t node_alloc_size;
 	unsigned int unmapped_child_count;
 
+	enum squat_index_flags flags;
 	enum file_lock_method lock_method;
 	uint32_t uidvalidity;
 
 	char *path;
 	int fd;
 	struct file_cache *file_cache;
+	struct dotlock_settings dotlock_set;
 
 	uoff_t locked_file_size;
 	const void *data;
@@ -130,7 +134,6 @@ struct squat_trie {
 
 	unsigned char default_normalize_map[256];
 
-	unsigned int mmap_disable:1;
 	unsigned int corrupted:1;
 };
 
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie.c
--- a/src/plugins/fts-squat/squat-trie.c	Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie.c	Fri Mar 07 08:15:35 2008 +0200
@@ -36,6 +36,7 @@ struct squat_trie_build_context {
 	struct squat_uidlist_build_context *uidlist_build_ctx;
 
 	struct file_lock *file_lock;
+	struct dotlock *dotlock;
 
 	uint32_t first_uid;
 	unsigned int compress_nodes:1;
@@ -126,7 +127,7 @@ static void node_free(struct squat_trie 
 
 struct squat_trie *
 squat_trie_init(const char *path, uint32_t uidvalidity,
-		enum file_lock_method lock_method, bool mmap_disable)
+		enum file_lock_method lock_method, enum squat_index_flags flags)
 {
 	struct squat_trie *trie;
 
@@ -136,8 +137,14 @@ squat_trie_init(const char *path, uint32
 	trie->fd = -1;
 	trie->lock_method = lock_method;
 	trie->uidvalidity = uidvalidity;
-	trie->mmap_disable = mmap_disable;
+	trie->flags = flags;
 	squat_trie_normalize_map_build(trie);
+
+	trie->dotlock_set.use_excl_lock =
+		(flags & SQUAT_INDEX_FLAG_DOTLOCK_USE_EXCL) != 0;
+	trie->dotlock_set.nfs_flush = (flags & SQUAT_INDEX_FLAG_NFS_FLUSH) != 0;
+	trie->dotlock_set.timeout = SQUAT_TRIE_LOCK_TIMEOUT;
+	trie->dotlock_set.stale_timeout = SQUAT_TRIE_DOTLOCK_STALE_TIMEOUT;
 	return trie;
 }
 
@@ -254,16 +261,26 @@ void squat_trie_refresh(struct squat_tri
 }
 
 static int squat_trie_lock(struct squat_trie *trie, int lock_type,
-			   struct file_lock **file_lock_r)
+			   struct file_lock **file_lock_r,
+			   struct dotlock **dotlock_r)
 {
 	int ret;
 
+	*file_lock_r = NULL;
+	*dotlock_r = NULL;
+
 	while (trie->fd != -1) {
-		ret = file_wait_lock(trie->fd, trie->path, lock_type,
-				     trie->lock_method, SQUAT_TRIE_LOCK_TIMEOUT,
-				     file_lock_r);
+		if (trie->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+			ret = file_wait_lock(trie->fd, trie->path, lock_type,
+					     trie->lock_method,
+					     SQUAT_TRIE_LOCK_TIMEOUT,
+					     file_lock_r);
+		} else {
+			ret = file_dotlock_create(&trie->dotlock_set,
+						  trie->path, 0, dotlock_r);
+		}
 		if (ret == 0) {
-			i_error("file_wait_lock(%s) failed: %m", trie->path);
+			i_error("squat trie %s: Locking timed out", trie->path);
 			return 0;
 		}
 		if (ret < 0)
@@ -275,7 +292,10 @@ static int squat_trie_lock(struct squat_
 		if (ret == 0)
 			return 1;
 
-		file_unlock(file_lock_r);
+		if (*file_lock_r != NULL)
+			file_unlock(file_lock_r);
+		else
+			file_dotlock_delete(dotlock_r);
 		if (ret < 0)
 			return -1;
 
@@ -1348,7 +1368,9 @@ squat_trie_renumber_uidlists(struct squa
 	squat_trie_iterate_deinit(iter);
 
 	/* lock the trie before we rename uidlist */
-	if (squat_trie_lock(ctx->trie, F_WRLCK, &ctx->file_lock) <= 0)
+	i_assert(ctx->file_lock == NULL && ctx->dotlock == NULL);
+	if (squat_trie_lock(ctx->trie, F_WRLCK,
+			    &ctx->file_lock, &ctx->dotlock) <= 0)
 		ret = -1;
 	return squat_uidlist_rebuild_finish(rebuild_ctx, ret < 0);
 }
@@ -1381,7 +1403,7 @@ static int squat_trie_map_header(struct 
 	}
 	i_assert(trie->fd != -1);
 
-	if (trie->mmap_disable) {
+	if ((trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0) {
 		ret = pread_full(trie->fd, &trie->hdr, sizeof(trie->hdr), 0);
 		if (ret <= 0) {
 			if (ret < 0) {
@@ -1424,19 +1446,24 @@ static int squat_trie_map(struct squat_t
 static int squat_trie_map(struct squat_trie *trie, bool building)
 {
 	struct file_lock *file_lock = NULL;
+	struct dotlock *dotlock = NULL;
 	bool changed;
 	int ret;
 
 	if (trie->fd != -1) {
-		if (squat_trie_lock(trie, F_RDLCK, &file_lock) <= 0)
+		if (squat_trie_lock(trie, F_RDLCK, &file_lock, &dotlock) <= 0)
 			return -1;
-		if (trie->mmap_disable && trie->file_cache == NULL)
+		if ((trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0 &&
+		    trie->file_cache == NULL)
 			trie->file_cache = file_cache_new(trie->fd);
 	}
 
 	ret = squat_trie_map_header(trie);
 	if (ret == 0) {
-		file_lock_free(&file_lock);
+		if (file_lock != NULL)
+			file_unlock(&file_lock);
+		else
+			file_dotlock_delete(&dotlock);
 		squat_trie_delete(trie);
 		squat_trie_close(trie);
 		squat_trie_header_init(trie);
@@ -1468,6 +1495,8 @@ static int squat_trie_map(struct squat_t
 
 	if (file_lock != NULL)
 		file_unlock(&file_lock);
+	if (dotlock != NULL)
+		file_dotlock_delete(&dotlock);
 	if (ret < 0)
 		return -1;
 
@@ -1513,10 +1542,11 @@ int squat_trie_build_init(struct squat_t
 
 static int squat_trie_write_lock(struct squat_trie_build_context *ctx)
 {
-	if (ctx->file_lock != NULL)
+	if (ctx->file_lock != NULL || ctx->dotlock != NULL)
 		return 0;
 
-	if (squat_trie_lock(ctx->trie, F_WRLCK, &ctx->file_lock) <= 0)
+	if (squat_trie_lock(ctx->trie, F_WRLCK,
+			    &ctx->file_lock, &ctx->dotlock) <= 0)
 		return -1;
 	return 0;
 }
@@ -1540,13 +1570,19 @@ static int squat_trie_write(struct squat
 			i_error("creat(%s) failed: %m", path);
 			return -1;
 		}
-		ret = file_wait_lock(fd, path, F_WRLCK, trie->lock_method,
-				     SQUAT_TRIE_LOCK_TIMEOUT, &file_lock);
-		if (ret <= 0) {
-			if (ret == 0)
-				i_error("file_wait_lock(%s) failed: %m", path);
-			(void)close(fd);
-			return -1;
+		if (trie->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+			ret = file_wait_lock(fd, path, F_WRLCK,
+					     trie->lock_method,
+					     SQUAT_TRIE_LOCK_TIMEOUT,
+					     &file_lock);
+			if (ret <= 0) {
+				if (ret == 0) {
+					i_error("file_wait_lock(%s) failed: %m",
+						path);
+				}
+				(void)close(fd);
+				return -1;
+			}
 		}
 
 		output = o_stream_create_fd(fd, 0, FALSE);
@@ -1614,7 +1650,8 @@ static int squat_trie_write(struct squat
 	if (ret < 0) {
 		if (unlink(path) < 0 && errno != ENOENT)
 			i_error("unlink(%s) failed: %m", path);
-		file_lock_free(&file_lock);
+		if (file_lock != NULL)
+			file_lock_free(&file_lock);
 	} else {
 		squat_trie_close_fd(trie);
 		trie->fd = fd;
@@ -1659,6 +1696,8 @@ int squat_trie_build_deinit(struct squat
 		else
 			file_lock_free(&ctx->file_lock);
 	}
+	if (ctx->dotlock != NULL)
+		file_dotlock_delete(&ctx->dotlock);
 	squat_uidlist_build_deinit(&ctx->uidlist_build_ctx);
 
 	i_free(ctx);
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie.h
--- a/src/plugins/fts-squat/squat-trie.h	Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie.h	Fri Mar 07 08:15:35 2008 +0200
@@ -3,6 +3,12 @@
 
 #include "file-lock.h"
 #include "seq-range-array.h"
+
+enum squat_index_flags {
+	SQUAT_INDEX_FLAG_MMAP_DISABLE		= 0x01,
+	SQUAT_INDEX_FLAG_NFS_FLUSH		= 0x02,
+	SQUAT_INDEX_FLAG_DOTLOCK_USE_EXCL	= 0x04
+};
 
 enum squat_index_type {
 	SQUAT_INDEX_TYPE_HEADER	= 0x01,
@@ -13,7 +19,8 @@ struct squat_trie_build_context;
 
 struct squat_trie *
 squat_trie_init(const char *path, uint32_t uidvalidity,
-		enum file_lock_method lock_method, bool mmap_disable);
+		enum file_lock_method lock_method,
+		enum squat_index_flags flags);
 void squat_trie_deinit(struct squat_trie **trie);
 
 void squat_trie_refresh(struct squat_trie *trie);
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-uidlist.c
--- a/src/plugins/fts-squat/squat-uidlist.c	Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-uidlist.c	Fri Mar 07 08:15:35 2008 +0200
@@ -39,6 +39,7 @@ struct squat_uidlist {
 	struct file_cache *file_cache;
 
 	struct file_lock *file_lock;
+	struct dotlock *dotlock;
 	uoff_t locked_file_size;
 
 	void *mmap_base;
@@ -438,7 +439,7 @@ static int squat_uidlist_map(struct squa
 		return 1;
 	}
 
-	if (!uidlist->trie->mmap_disable) {
+	if ((uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) == 0) {
 		if (mmap_hdr == NULL || uidlist->building ||
 		    uidlist->mmap_size < mmap_hdr->used_file_size) {
 			if (squat_uidlist_mmap(uidlist) < 0)
@@ -466,7 +467,8 @@ static int squat_uidlist_map(struct squa
 		uidlist->data = NULL;
 		uidlist->data_size = 0;
 	}
-	if (uidlist->file_cache == NULL && uidlist->trie->mmap_disable)
+	if (uidlist->file_cache == NULL &&
+	    (uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0)
 		uidlist->file_cache = file_cache_new(uidlist->fd);
 	return squat_uidlist_map_header(uidlist);
 }
@@ -516,6 +518,8 @@ static void squat_uidlist_close(struct s
 		file_cache_free(&uidlist->file_cache);
 	if (uidlist->file_lock != NULL)
 		file_lock_free(&uidlist->file_lock);
+	if (uidlist->dotlock != NULL)
+		file_dotlock_delete(&uidlist->dotlock);
 	if (uidlist->fd != -1) {
 		if (close(uidlist->fd) < 0)


More information about the dovecot-cvs mailing list