[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.3, 1.4 mail-index-private.h, 1.2, 1.3 mail-index.c, 1.108, 1.109 mail-index.h, 1.99, 1.100 mail-transaction-log-private.h, 1.1, 1.2 mail-transaction-log.c, 1.3, 1.4

cras at procontrol.fi cras at procontrol.fi
Wed Apr 28 05:00:42 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv830/src/lib-index

Modified Files:
	mail-index-lock.c mail-index-private.h mail-index.c 
	mail-index.h mail-transaction-log-private.h 
	mail-transaction-log.c 
Log Message:
Added fcntl_lock_disable setting to allow indexes to work with NFS. Some
other locking fixes.



Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mail-index-lock.c	28 Apr 2004 01:21:42 -0000	1.3
+++ mail-index-lock.c	28 Apr 2004 02:00:39 -0000	1.4
@@ -76,6 +76,24 @@
 	}
 }
 
+static int mail_index_lock_mprotect(struct mail_index *index, int lock_type)
+{
+	int prot;
+
+	if (index->map != NULL &&
+	    !MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
+		prot = lock_type == F_UNLCK ? PROT_NONE :
+			lock_type == F_WRLCK ? (PROT_READ|PROT_WRITE) :
+			PROT_READ;
+		if (mprotect(index->map->mmap_base,
+			     index->map->file_size, prot) < 0) {
+			mail_index_set_syscall_error(index, "mprotect()");
+			return -1;
+		}
+	}
+	return 0;
+}
+
 static int mail_index_lock(struct mail_index *index, int lock_type,
 			   unsigned int timeout_secs, int update_index,
 			   unsigned int *lock_id_r)
@@ -84,6 +102,15 @@
 
 	i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK);
 
+	if (index->fcntl_locks_disable) {
+		/* FIXME: exclusive locking will rewrite the index file every
+		   time. shouldn't really be needed.. reading doesn't require
+		   locks then, though */
+		if (lock_type == F_WRLCK)
+			return 0;
+	} else {
+	}
+
 	if (lock_type == F_WRLCK && index->lock_type == F_RDLCK) {
 		/* drop shared locks */
 		i_assert(index->excl_lock_count == 0);
@@ -148,16 +175,8 @@
 		*lock_id_r = index->lock_id + 1;
 	}
 
-	if (index->map != NULL &&
-	    !MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
-		int prot = PROT_READ | (lock_type == F_WRLCK ? PROT_WRITE : 0);
-		if (mprotect(index->map->mmap_base,
-			     index->map->file_size, prot) < 0) {
-			mail_index_set_syscall_error(index, "mprotect()");
-			return -1;
-		}
-	}
-
+	if (mail_index_lock_mprotect(index, lock_type) < 0)
+		return -1;
 	return 1;
 }
 
@@ -189,6 +208,8 @@
 	if (fd == -1)
 		return -1;
 
+	(void)mail_index_lock_mprotect(index, F_RDLCK);
+
 	ret = write_full(fd, index->map->hdr, sizeof(*index->map->hdr));
 	if (ret < 0 || write_full(fd, index->map->records,
 				  index->map->records_count *
@@ -300,7 +321,7 @@
 
 	mail_index_unlock(index, lock_id);
 
-	*lock_id_r = 0;
+	*lock_id_r = index->lock_id + 1;
 	return mail_index_lock_exclusive_copy(index);
 }
 
@@ -314,7 +335,6 @@
 							  "file_try_lock()");
 			return -1;
 		}
-		index->lock_id--;
 	}
 
 	if (fsync(index->fd) < 0) {
@@ -367,7 +387,7 @@
 		}
 	} else {
 		/* exclusive lock */
-		i_assert(lock_id == index->lock_id+1);
+		i_assert(lock_id == index->lock_id + 1);
 		i_assert(index->excl_lock_count > 0);
 		if (--index->excl_lock_count == 0)
 			mail_index_excl_unlock_finish(index);
@@ -376,15 +396,13 @@
 	if (index->shared_lock_count == 0 && index->excl_lock_count == 0) {
 		index->lock_id += 2;
 		index->lock_type = F_UNLCK;
-		if (index->map != NULL &&
-		    !MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
-			if (mprotect(index->map->mmap_base,
-				     index->map->file_size, PROT_NONE) < 0)
+		(void)mail_index_lock_mprotect(index, F_UNLCK);
+		if (!index->fcntl_locks_disable) {
+			if (file_wait_lock(index->fd, F_UNLCK) < 0) {
 				mail_index_set_syscall_error(index,
-							     "mprotect()");
+					"file_wait_lock()");
+			}
 		}
-		if (file_wait_lock(index->fd, F_UNLCK) < 0)
-			mail_index_set_syscall_error(index, "file_wait_lock()");
 	}
 }
 

Index: mail-index-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mail-index-private.h	28 Apr 2004 00:21:00 -0000	1.2
+++ mail-index-private.h	28 Apr 2004 02:00:39 -0000	1.3
@@ -1,6 +1,7 @@
 #ifndef __MAIL_INDEX_PRIVATE_H
 #define __MAIL_INDEX_PRIVATE_H
 
+#include "file-dotlock.h"
 #include "mail-index.h"
 
 struct mail_transaction_header;
@@ -70,6 +71,7 @@
 	int lock_type, shared_lock_count, excl_lock_count;
 	unsigned int lock_id, copy_lock_id;
 	char *copy_lock_path;
+	struct dotlock dotlock;
 
 	char *error;
 	unsigned int nodiskspace:1;
@@ -79,6 +81,7 @@
 	unsigned int log_locked:1;
 	unsigned int mmap_disable:1;
 	unsigned int mmap_no_write:1;
+	unsigned int fcntl_locks_disable:1;
 	unsigned int readonly:1;
 	unsigned int fsck:1;
 };

Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -d -r1.108 -r1.109
--- mail-index.c	28 Apr 2004 01:21:42 -0000	1.108
+++ mail-index.c	28 Apr 2004 02:00:39 -0000	1.109
@@ -575,6 +575,8 @@
 			(flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
 		index->mmap_no_write =
 			(flags & MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE) != 0;
+		index->fcntl_locks_disable =
+			(flags & MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE) != 0;
 		index->readonly = FALSE;
 
 		index->filepath = i_strconcat(index->dir, "/",

Index: mail-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- mail-index.h	28 Apr 2004 00:21:00 -0000	1.99
+++ mail-index.h	28 Apr 2004 02:00:39 -0000	1.100
@@ -24,8 +24,8 @@
 	   OSes that don't have unified buffer cache
 	   (currently OpenBSD <= 3.5) */
 	MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE	= 0x08,
-	/* Use only dotlocking, no fcntl() */
-	MAIL_INDEX_OPEN_FLAG_USE_DOTLOCKS	= 0x10
+	/* Don't use fcntl() locking */
+	MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE= 0x10
 };
 
 enum mail_index_header_compat_flags {

Index: mail-transaction-log-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log-private.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mail-transaction-log-private.h	27 Apr 2004 20:25:53 -0000	1.1
+++ mail-transaction-log-private.h	28 Apr 2004 02:00:39 -0000	1.2
@@ -1,6 +1,7 @@
 #ifndef __MAIL_TRANSACTION_LOG_VIEW_H
 #define __MAIL_TRANSACTION_LOG_VIEW_H
 
+#include "file-dotlock.h"
 #include "mail-transaction-log.h"
 
 struct mail_transaction_log_file {
@@ -12,6 +13,7 @@
 	char *filepath;
 	int fd;
 	int lock_type;
+	struct dotlock dotlock;
 
 	ino_t st_ino;
 	dev_t st_dev;

Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mail-transaction-log.c	28 Apr 2004 01:21:42 -0000	1.3
+++ mail-transaction-log.c	28 Apr 2004 02:00:39 -0000	1.4
@@ -16,6 +16,11 @@
 #include <stddef.h>
 #include <sys/stat.h>
 
+/* this lock should never exist for a long time.. */
+#define LOG_DOTLOCK_TIMEOUT 30
+#define LOG_DOTLOCK_STALE_TIMEOUT 0
+#define LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT 120
+
 struct mail_transaction_add_ctx {
 	struct mail_transaction_log *log;
 	struct mail_index_view *view;
@@ -117,6 +122,54 @@
 }
 
 static int
+mail_transaction_log_file_dotlock(struct mail_transaction_log_file *file,
+				  int lock_type)
+{
+	int ret;
+
+	if (lock_type == F_UNLCK) {
+		ret = file_unlock_dotlock(file->filepath, &file->dotlock);
+		if (ret < 0) {
+			mail_index_file_set_syscall_error(file->log->index,
+				file->filepath, "file_unlock_dotlock()");
+			return -1;
+		}
+		file->lock_type = F_UNLCK;
+
+		if (ret == 0) {
+			mail_index_set_error(file->log->index,
+				"Dotlock was lost for transaction log file %s",
+				file->filepath);
+			return -1;
+		}
+		return 0;
+	}
+
+	ret = file_lock_dotlock(file->filepath, NULL, FALSE,
+				LOG_DOTLOCK_TIMEOUT,
+				LOG_DOTLOCK_STALE_TIMEOUT,
+				LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT,
+				NULL, NULL, &file->dotlock);
+	if (ret > 0) {
+		file->lock_type = F_WRLCK;
+		return 0;
+	}
+	if (ret < 0) {
+		mail_index_file_set_syscall_error(file->log->index,
+						  file->filepath,
+						  "file_lock_dotlock()");
+		return -1;
+	}
+
+	mail_index_set_error(file->log->index,
+			     "Timeout while waiting for release of "
+			     "dotlock for transaction log file %s",
+			     file->filepath);
+	file->log->index->index_lock_timeout = TRUE;
+	return -1;
+}
+
+static int
 mail_transaction_log_file_lock(struct mail_transaction_log_file *file,
 			       int lock_type)
 {
@@ -128,6 +181,9 @@
 		i_assert(file->lock_type == F_UNLCK);
 	}
 
+	if (file->log->index->fcntl_locks_disable)
+		return mail_transaction_log_file_dotlock(file, lock_type);
+
 	ret = file_wait_lock_full(file->fd, lock_type, DEFAULT_LOCK_TIMEOUT,
 				  NULL, NULL);
 	if (ret > 0) {
@@ -233,8 +289,9 @@
 	unsigned int lock_id;
 	int fd, fd2, ret;
 
-	/* this lock should never exist for a long time.. */
-	fd = file_dotlock_open(path, NULL, 30, 0, 120, NULL, NULL);
+	fd = file_dotlock_open(path, NULL, LOG_DOTLOCK_TIMEOUT,
+			       LOG_DOTLOCK_STALE_TIMEOUT,
+			       LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT, NULL, NULL);
 	if (fd == -1) {
 		mail_index_file_set_syscall_error(index, path,
 						  "file_dotlock_open()");



More information about the dovecot-cvs mailing list