changeset 4968:1baf9dd3fc40 HEAD

Added dotlock_use_excl setting.
author Timo Sirainen <tss@iki.fi>
date Thu, 28 Dec 2006 18:27:53 +0200
parents 1104fc097321
children 5c18ac362f65
files dovecot-example.conf src/deliver/duplicate.c src/lib-index/mail-cache.c src/lib-index/mail-hash.c src/lib-index/mail-index-private.h src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-transaction-log.c src/lib-index/mailbox-list-index-private.h src/lib-index/mailbox-list-index.c src/lib-storage/index/index-storage.c src/lib-storage/list/subscription-file.c src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib-storage/mailbox-list.h src/master/master-settings-defs.c src/master/master-settings.c src/master/master-settings.h src/plugins/convert/convert-storage.c src/plugins/quota/quota-maildir.c
diffstat 20 files changed, 54 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/dovecot-example.conf	Thu Dec 28 18:07:19 2006 +0200
+++ b/dovecot-example.conf	Thu Dec 28 18:27:53 2006 +0200
@@ -280,6 +280,11 @@
 # which use separate caches for them, such as OpenBSD.
 #mmap_no_write = no
 
+# Rely on O_EXCL to work when creating dotlock files. The default is to use
+# hard linking. O_EXCL makes the dotlocking faster, but it doesn't always
+# work with NFS.
+#dotlock_use_excl = no
+
 # Don't use fsync() or fdatasync() calls. This makes the performance better
 # at the cost of potential data loss if the server (or the file server)
 # goes down.
--- a/src/deliver/duplicate.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/deliver/duplicate.c	Thu Dec 28 18:27:53 2006 +0200
@@ -9,6 +9,7 @@
 #include "hash.h"
 #include "duplicate.h"
 
+#include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -240,6 +241,8 @@
 
 void duplicate_init(void)
 {
+	duplicate_dotlock_set.use_excl_lock =
+		getenv("DOTLOCK_USE_EXCL") != NULL;
 }
 
 void duplicate_deinit(void)
--- a/src/lib-index/mail-cache.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-cache.c	Thu Dec 28 18:27:53 2006 +0200
@@ -304,6 +304,7 @@
 		hash_create(default_pool, cache->field_pool, 0,
 			    strcase_hash, (hash_cmp_callback_t *)strcasecmp);
 
+	cache->dotlock_settings.use_excl_lock = index->use_excl_dotlocks;
 	cache->dotlock_settings.timeout = MAIL_CACHE_LOCK_TIMEOUT;
 	cache->dotlock_settings.stale_timeout = MAIL_CACHE_LOCK_CHANGE_TIMEOUT;
 
--- a/src/lib-index/mail-hash.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-hash.c	Thu Dec 28 18:27:53 2006 +0200
@@ -53,6 +53,7 @@
 	int lock_type;
 	struct file_lock *file_lock;
 	struct dotlock *dotlock;
+	struct dotlock_settings dotlock_settings;
 
 	struct mail_hash_header *hdr;
 
@@ -71,7 +72,7 @@
 #define HASH_RECORD_IDX(hash, idx) \
 	PTR_OFFSET((hash)->records_base, ((idx) - 1) * (hash)->record_size)
 
-const struct dotlock_settings dotlock_settings = {
+const struct dotlock_settings default_dotlock_settings = {
 	MEMBER(temp_prefix) NULL,
 	MEMBER(lock_suffix) NULL,
 
@@ -414,8 +415,8 @@
 					  &hash->file_lock);
 	} else {
 		i_assert(hash->dotlock == NULL);
-		return file_dotlock_create(&dotlock_settings, hash->filepath,
-					   0, &hash->dotlock);
+		return file_dotlock_create(&hash->dotlock_settings,
+					   hash->filepath, 0, &hash->dotlock);
 	}
 }
 
@@ -493,7 +494,8 @@
 	uoff_t file_size;
 	int fd;
 
-	fd = file_dotlock_open(&dotlock_settings, hash->filepath, 0, &dotlock);
+	fd = file_dotlock_open(&hash->dotlock_settings,
+			       hash->filepath, 0, &dotlock);
 	if (fd == -1) {
 		mail_hash_set_syscall_error(hash, "file_dotlock_open()");
 		return -1;
@@ -559,6 +561,8 @@
 	hash->suffix = i_strdup(suffix);
 	hash->record_size = record_size;
 	hash->fd = -1;
+	hash->dotlock_settings = default_dotlock_settings;
+	hash->dotlock_settings.use_excl_lock = index->use_excl_dotlocks;
 
 	hash->key_hash_cb = key_hash_cb;
 	hash->rec_hash_cb = rec_hash_cb;
--- a/src/lib-index/mail-index-private.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-index-private.h	Thu Dec 28 18:27:53 2006 +0200
@@ -183,6 +183,7 @@
 	unsigned int mmap_disable:1;
 	unsigned int fsync_disable:1;
 	unsigned int mmap_no_write:1;
+	unsigned int use_excl_dotlocks:1;
 	unsigned int readonly:1;
 	unsigned int fsck:1;
 	unsigned int sync_update:1;
--- a/src/lib-index/mail-index.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-index.c	Thu Dec 28 18:27:53 2006 +0200
@@ -1569,6 +1569,8 @@
 			(flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
 		index->mmap_no_write =
 			(flags & MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE) != 0;
+		index->use_excl_dotlocks =
+			(flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0;
 		index->fsync_disable =
 			(flags & MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE) != 0;
 		index->lock_method = lock_method;
--- a/src/lib-index/mail-index.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-index.h	Thu Dec 28 18:27:53 2006 +0200
@@ -20,8 +20,10 @@
 	   OSes that don't have unified buffer cache
 	   (currently OpenBSD <= 3.5) */
 	MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE	= 0x08,
+	/* Rely on O_EXCL when creating dotlocks */
+	MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL	= 0x10,
 	/* Don't fsync() or fdatasync() */
-	MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE	= 0x10
+	MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE	= 0x20
 };
 
 enum mail_index_header_compat_flags {
--- a/src/lib-index/mail-transaction-log.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mail-transaction-log.c	Thu Dec 28 18:27:53 2006 +0200
@@ -223,6 +223,7 @@
 	log = i_new(struct mail_transaction_log, 1);
 	log->index = index;
 
+	log->dotlock_settings.use_excl_lock = index->use_excl_dotlocks;
 	log->dotlock_settings.timeout = LOG_DOTLOCK_TIMEOUT;
 	log->dotlock_settings.stale_timeout = LOG_DOTLOCK_STALE_TIMEOUT;
 
--- a/src/lib-index/mailbox-list-index-private.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mailbox-list-index-private.h	Thu Dec 28 18:27:53 2006 +0200
@@ -1,6 +1,7 @@
 #ifndef __MAILBOX_LIST_INDEX_PRIVATE_H
 #define __MAILBOX_LIST_INDEX_PRIVATE_H
 
+#include "file-dotlock.h"
 #include "mailbox-list-index.h"
 
 #define MAILBOX_LIST_INDEX_MAJOR_VERSION 1
@@ -55,6 +56,7 @@
 	char separator;
 	struct mail_index *mail_index;
 	struct file_cache *file_cache;
+	struct dotlock_settings dotlock_set;
 
 	int fd;
 
--- a/src/lib-index/mailbox-list-index.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-index/mailbox-list-index.c	Thu Dec 28 18:27:53 2006 +0200
@@ -35,7 +35,7 @@
 	unsigned int failed:1;
 };
 
-const struct dotlock_settings dotlock_set = {
+const struct dotlock_settings default_dotlock_set = {
 	MEMBER(temp_prefix) NULL,
 	MEMBER(lock_suffix) NULL,
 
@@ -219,7 +219,8 @@
 	struct dotlock *dotlock;
 	int fd, ret;
 
-	fd = file_dotlock_open(&dotlock_set, index->filepath, 0, &dotlock);
+	fd = file_dotlock_open(&index->dotlock_set, index->filepath,
+			       0, &dotlock);
 	if (fd == -1) {
 		mailbox_list_index_set_syscall_error(index,
 						     "file_dotlock_open()");
@@ -314,6 +315,8 @@
 	index->mail_index = mail_index;
 	index->fd = -1;
 	index->mmap_disable = mail_index->mmap_disable;
+	index->dotlock_set = default_dotlock_set;
+	index->dotlock_set.use_excl_lock = mail_index->use_excl_dotlocks;
 	return index;
 }
 
--- a/src/lib-storage/index/index-storage.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-storage/index/index-storage.c	Thu Dec 28 18:27:53 2006 +0200
@@ -339,6 +339,8 @@
 	if ((storage->flags & MAIL_STORAGE_FLAG_MMAP_NO_WRITE) != 0)
 #endif
 		index_flags |= MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE;
+	if ((storage->flags & MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0)
+		index_flags |= MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL;
 
 	ret = mail_index_open(ibox->index, index_flags, storage->lock_method);
 	if (ret <= 0 || ibox->move_to_memory) {
--- a/src/lib-storage/list/subscription-file.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-storage/list/subscription-file.c	Thu Dec 28 18:27:53 2006 +0200
@@ -88,6 +88,8 @@
 		name = "INBOX";
 
 	memset(&dotlock_set, 0, sizeof(dotlock_set));
+	dotlock_set.use_excl_lock =
+		(list->flags & MAILBOX_LIST_FLAG_DOTLOCK_USE_EXCL) != 0;
 	dotlock_set.temp_prefix = temp_prefix;
 	dotlock_set.timeout = SUBSCRIPTION_FILE_LOCK_TIMEOUT;
 	dotlock_set.stale_timeout = SUBSCRIPTION_FILE_CHANGE_TIMEOUT;
--- a/src/lib-storage/mail-storage.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-storage/mail-storage.c	Thu Dec 28 18:27:53 2006 +0200
@@ -76,6 +76,8 @@
 		*flags_r |= MAIL_STORAGE_FLAG_MMAP_DISABLE;
 	if (getenv("MMAP_NO_WRITE") != NULL)
 		*flags_r |= MAIL_STORAGE_FLAG_MMAP_NO_WRITE;
+	if (getenv("DOTLOCK_USE_EXCL") != NULL)
+		*flags_r |= MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL;
 	if (getenv("MAIL_READ_MMAPED") != NULL)
 		*flags_r |= MAIL_STORAGE_FLAG_MMAP_MAILS;
 	if (getenv("MAIL_SAVE_CRLF") != NULL)
@@ -380,6 +382,8 @@
 		list_flags |= MAILBOX_LIST_FLAG_INBOX;
 	if ((storage_flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0)
 		list_flags |= MAILBOX_LIST_FLAG_FULL_FS_ACCESS;
+	if ((storage_flags & MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0)
+		list_flags |= MAILBOX_LIST_FLAG_DOTLOCK_USE_EXCL;
 	return list_flags;
 }
 
--- a/src/lib-storage/mail-storage.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-storage/mail-storage.h	Thu Dec 28 18:27:53 2006 +0200
@@ -31,8 +31,10 @@
 	/* Don't autocreate any directories. If they don't exist,
 	   fail to create the storage. */
 	MAIL_STORAGE_FLAG_NO_AUTOCREATE		= 0x200,
+	/* Rely on O_EXCL when creating dotlocks */
+	MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL	= 0x400,
 	/* Ths storage contains INBOX */
-	MAIL_STORAGE_FLAG_HAS_INBOX		= 0x400
+	MAIL_STORAGE_FLAG_HAS_INBOX		= 0x800
 };
 
 enum mailbox_open_flags {
--- a/src/lib-storage/mailbox-list.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/lib-storage/mailbox-list.h	Thu Dec 28 18:27:53 2006 +0200
@@ -10,7 +10,9 @@
 	/* This mailbox list contains INBOX. Match case-insensitively for it. */
 	MAILBOX_LIST_FLAG_INBOX			= 0x02,
 	/* Allow full filesystem access with absolute or relative paths. */
-	MAILBOX_LIST_FLAG_FULL_FS_ACCESS	= 0x04
+	MAILBOX_LIST_FLAG_FULL_FS_ACCESS	= 0x04,
+	/* Rely on O_EXCL when creating dotlocks */
+	MAILBOX_LIST_FLAG_DOTLOCK_USE_EXCL	= 0x08
 };
 
 enum mailbox_info_flags {
--- a/src/master/master-settings-defs.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/master/master-settings-defs.c	Thu Dec 28 18:27:53 2006 +0200
@@ -72,6 +72,7 @@
 	DEF(SET_BOOL, mail_read_mmaped),
 	DEF(SET_BOOL, mmap_disable),
 	DEF(SET_BOOL, mmap_no_write),
+	DEF(SET_BOOL, dotlock_use_excl),
 	DEF(SET_BOOL, fsync_disable),
 	DEF(SET_STR, lock_method),
 	DEF(SET_BOOL, maildir_stat_dirs),
--- a/src/master/master-settings.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/master/master-settings.c	Thu Dec 28 18:27:53 2006 +0200
@@ -223,6 +223,7 @@
 #else
 	MEMBER(mmap_no_write) FALSE,
 #endif
+	MEMBER(dotlock_use_excl) FALSE,
 	MEMBER(fsync_disable) FALSE,
 	MEMBER(lock_method) "fcntl",
 	MEMBER(maildir_stat_dirs) FALSE,
--- a/src/master/master-settings.h	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/master/master-settings.h	Thu Dec 28 18:27:53 2006 +0200
@@ -80,6 +80,7 @@
 	bool mail_read_mmaped;
 	bool mmap_disable;
 	bool mmap_no_write;
+	bool dotlock_use_excl;
 	bool fsync_disable;
 	const char *lock_method;
 	bool maildir_stat_dirs;
--- a/src/plugins/convert/convert-storage.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/plugins/convert/convert-storage.c	Thu Dec 28 18:27:53 2006 +0200
@@ -10,7 +10,7 @@
 
 #define CONVERT_LOCK_FILENAME ".dovecot.convert"
 
-const struct dotlock_settings dotlock_settings = {
+struct dotlock_settings dotlock_settings = {
 	MEMBER(temp_prefix) NULL,
 	MEMBER(lock_suffix) NULL,
 
@@ -233,6 +233,9 @@
 	}
 
         path = t_strconcat(home_dir, "/"CONVERT_LOCK_FILENAME, NULL);
+	dotlock_settings.use_excl_lock =
+		(source_storage->flags &
+		 MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0;
 	ret = file_dotlock_create(&dotlock_settings, path, 0, &dotlock);
 	if (ret <= 0) {
 		if (ret == 0)
--- a/src/plugins/quota/quota-maildir.c	Thu Dec 28 18:07:19 2006 +0200
+++ b/src/plugins/quota/quota-maildir.c	Thu Dec 28 18:27:53 2006 +0200
@@ -46,7 +46,7 @@
 
 extern struct quota_backend quota_backend_maildir;
 
-const struct dotlock_settings dotlock_settings = {
+struct dotlock_settings dotlock_settings = {
 	MEMBER(temp_prefix) NULL,
 	MEMBER(lock_suffix) NULL,
 
@@ -216,6 +216,7 @@
 
 	i_assert(root->fd == -1);
 
+	dotlock_settings.use_excl_lock = getenv("DOTLOCK_USE_EXCL") != NULL;
 	fd = file_dotlock_open(&dotlock_settings, path,
 			       DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock);
 	if (fd == -1) {