[dovecot-cvs] dovecot/src/lib-index mail-cache.c, 1.48, 1.49 mail-index-lock.c, 1.32, 1.33 mail-index-private.h, 1.30, 1.31 mail-index-view.c, 1.23, 1.24 mail-index.c, 1.152, 1.153 mail-index.h, 1.131, 1.132 mail-transaction-log.c, 1.62, 1.63

cras at dovecot.org cras at dovecot.org
Sun Oct 10 20:25:47 EEST 2004


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv11749/src/lib-index

Modified Files:
	mail-cache.c mail-index-lock.c mail-index-private.h 
	mail-index-view.c mail-index.c mail-index.h 
	mail-transaction-log.c 
Log Message:
Replaced fcntl_locks_disable with lock_method, so it's now possible to use
flock() to lock indexes.



Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- mail-cache.c	8 Oct 2004 17:51:48 -0000	1.48
+++ mail-cache.c	10 Oct 2004 17:25:44 -0000	1.49
@@ -3,7 +3,6 @@
 #include "lib.h"
 #include "buffer.h"
 #include "hash.h"
-#include "file-lock.h"
 #include "mmap-util.h"
 #include "write-full.h"
 #include "mail-cache-private.h"
@@ -257,8 +256,11 @@
 	}
 
 	for (i = 0; i < 3; i++) {
-		if ((ret = file_wait_lock(cache->fd, F_WRLCK)) <= 0) {
-			mail_cache_set_syscall_error(cache, "file_wait_lock()");
+		ret = mail_index_lock_fd(cache->index, cache->fd, F_WRLCK,
+					 MAIL_INDEX_LOCK_SECS);
+		if (ret <= 0) {
+			mail_cache_set_syscall_error(cache,
+				"mail_index_wait_lock_fd()");
 			break;
 		}
 		cache->locked = TRUE;
@@ -321,8 +323,10 @@
                 mail_cache_update_need_compress(cache);
 	}
 
-	if (file_wait_lock(cache->fd, F_UNLCK) <= 0)
-		mail_cache_set_syscall_error(cache, "file_wait_lock(F_UNLCK)");
+	if (mail_index_lock_fd(cache->index, cache->fd, F_UNLCK, 0) <= 0) {
+		mail_cache_set_syscall_error(cache,
+			"mail_index_wait_lock_fd(F_UNLCK)");
+	}
 }
 
 struct mail_cache_view *

Index: mail-index-lock.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- mail-index-lock.c	5 Sep 2004 17:53:45 -0000	1.32
+++ mail-index-lock.c	10 Oct 2004 17:25:44 -0000	1.33
@@ -21,13 +21,92 @@
 #include "lib.h"
 #include "buffer.h"
 #include "mmap-util.h"
-#include "file-lock.h"
 #include "write-full.h"
 #include "mail-index-private.h"
 
 #include <stdio.h>
 #include <sys/stat.h>
 
+#ifdef HAVE_FLOCK
+#  include <sys/file.h>
+#endif
+
+#define MAIL_INDEX_LOCK_WAIT_TIME 120
+
+int mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
+		       unsigned int timeout_secs)
+{
+	if (timeout_secs != 0) alarm(MAIL_INDEX_LOCK_WAIT_TIME);
+
+	switch (index->lock_method) {
+	case MAIL_INDEX_LOCK_FCNTL: {
+#ifndef HAVE_FCNTL
+		i_fatal("fcntl() locks not supported");
+#else
+		struct flock fl;
+
+		fl.l_type = lock_type;
+		fl.l_whence = SEEK_SET;
+		fl.l_start = 0;
+		fl.l_len = 0;
+
+		if (fcntl(fd, timeout_secs ? F_SETLKW : F_SETLK, &fl) < 0) {
+			if (timeout_secs == 0 &&
+			    (errno == EACCES || errno == EAGAIN)) {
+				/* locked by another process */
+				return 0;
+			}
+
+			if (errno == EINTR) {
+				/* most likely alarm hit, meaning we timeouted.
+				   even if not, we probably want to be killed
+				   so stop blocking. */
+				errno = EAGAIN;
+				if (timeout_secs != 0) alarm(0);
+				return 0;
+			}
+		}
+		if (timeout_secs != 0) alarm(0);
+		return 1;
+#endif
+	}
+	case MAIL_INDEX_LOCK_FLOCK: {
+#ifndef HAVE_FLOCK
+		i_fatal("flock() locks not supported");
+#else
+		int operation = timeout_secs != 0 ? 0 : LOCK_NB;
+
+		switch (lock_type) {
+		case F_RDLCK:
+			operation |= LOCK_SH;
+			break;
+		case F_WRLCK:
+			operation |= LOCK_EX;
+			break;
+		case F_UNLCK:
+			operation |= LOCK_UN;
+			break;
+		}
+
+		if (flock(fd, operation) < 0) {
+			if (errno == EWOULDBLOCK || errno == EINTR) {
+				/* a) locked by another process,
+				   b) timeouted */
+				if (timeout_secs != 0) alarm(0);
+				return 0;
+			}
+		}
+		if (timeout_secs != 0) alarm(0);
+		return 1;
+#endif
+	}
+	case MAIL_INDEX_LOCK_DOTLOCK:
+		/* we shouldn't get here */
+		break;
+	}
+	i_unreached();
+}
+
 int mail_index_map_lock_mprotect(struct mail_index *index,
 				 struct mail_index_map *map, int lock_type)
 {
@@ -91,7 +170,7 @@
 	if (ret > 0)
 		return 1;
 
-	if (index->fcntl_locks_disable) {
+	if (index->lock_type == MAIL_INDEX_LOCK_DOTLOCK) {
 		/* FIXME: exclusive locking will rewrite the index file every
 		   time. shouldn't really be needed.. reading doesn't require
 		   locks then, though */
@@ -111,12 +190,8 @@
 	}
 
 	if (lock_type == F_RDLCK || !index->log_locked) {
-		ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
-					  NULL, NULL);
-		if (ret < 0) {
-			mail_index_set_syscall_error(index, "file_wait_lock()");
-			return -1;
-		}
+		ret = mail_index_lock_fd(index, index->fd, lock_type,
+					 timeout_secs);
 	} else {
 		/* this is kind of kludgy. we wish to avoid deadlocks while
 		   trying to lock transaction log, but it can happen if our
@@ -132,14 +207,14 @@
 		   so, the workaround for this problem is that we simply try
 		   locking once. if it doesn't work, just rewrite the file.
 		   hopefully there won't be any other deadlocking issues. :) */
-		ret = file_try_lock(index->fd, lock_type);
-		if (ret < 0) {
-			mail_index_set_syscall_error(index, "file_try_lock()");
-			return -1;
-		}
+		ret = mail_index_lock_fd(index, index->fd, lock_type, 0);
+	}
+	if (ret <= 0) {
+		if (ret == 0)
+			return 0;
+		mail_index_set_syscall_error(index, "mail_index_lock_fd()");
+		return -1;
 	}
-	if (ret == 0)
-		return 0;
 
 	if (index->lock_type == F_UNLCK)
 		index->lock_id += 2;
@@ -163,7 +238,7 @@
 {
 	int ret;
 
-	ret = mail_index_lock(index, F_RDLCK, DEFAULT_LOCK_TIMEOUT,
+	ret = mail_index_lock(index, F_RDLCK, MAIL_INDEX_LOCK_SECS,
 			      update_index, lock_id_r);
 	if (ret > 0)
 		return 0;
@@ -340,12 +415,12 @@
 			(void)close(fd);
 	}
 
-	if (index->shared_lock_count > 0 && !index->fcntl_locks_disable) {
+	if (index->shared_lock_count > 0 &&
+	    index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
 		/* leave ourself shared locked. */
-		if (file_try_lock(index->fd, F_RDLCK) <= 0) {
+		if (mail_index_lock_fd(index, index->fd, F_RDLCK, 0) <= 0) {
 			mail_index_file_set_syscall_error(index,
-							  index->copy_lock_path,
-							  "file_try_lock()");
+				index->copy_lock_path, "mail_index_lock_fd()");
 		}
 		i_assert(index->lock_type == F_WRLCK);
 		index->lock_type = F_RDLCK;
@@ -384,10 +459,11 @@
 		index->lock_id += 2;
 		index->lock_type = F_UNLCK;
 		(void)mail_index_lock_mprotect(index, F_UNLCK);
-		if (!index->fcntl_locks_disable) {
-			if (file_wait_lock(index->fd, F_UNLCK) < 0) {
+		if (index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
+			if (mail_index_lock_fd(index, index->fd,
+					       F_UNLCK, 0) < 0) {
 				mail_index_set_syscall_error(index,
-					"file_wait_lock()");
+					"mail_index_lock_fd()");
 			}
 		}
 	}

Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- mail-index-private.h	3 Oct 2004 16:32:59 -0000	1.30
+++ mail-index-private.h	10 Oct 2004 17:25:44 -0000	1.31
@@ -1,11 +1,17 @@
 #ifndef __MAIL_INDEX_PRIVATE_H
 #define __MAIL_INDEX_PRIVATE_H
 
+/* Make sure F_RDLCK, F_WRLCK and F_UNLCK get defined */
+#include <unistd.h>
+#include <fcntl.h>
+
 #include "file-dotlock.h"
 #include "mail-index.h"
 
 struct mail_transaction_header;
 
+/* How many seconds to wait a lock for index file. */
+#define MAIL_INDEX_LOCK_SECS 120
 /* Index file is grown exponentially when we're adding less than this many
    records. */
 #define MAIL_INDEX_MAX_POWER_GROW (1024*1024 / sizeof(struct mail_index_record))
@@ -91,6 +97,7 @@
 	unsigned int lock_id;
 	char *copy_lock_path;
 	struct dotlock dotlock;
+        enum mail_index_lock_method lock_method;
 
 	unsigned int last_grow_count;
 
@@ -102,7 +109,6 @@
 	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;
 };
@@ -127,6 +133,9 @@
 int mail_index_map_lock_mprotect(struct mail_index *index,
 				 struct mail_index_map *map, int lock_type);
 
+int mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
+		       unsigned int timeout_secs);
+
 /* Map index file to memory, replacing the previous mapping for index.
    Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
    returns 1 but sets index->fsck = TRUE. */

Index: mail-index-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-view.c	10 Oct 2004 13:55:12 -0000	1.23
+++ mail-index-view.c	10 Oct 2004 17:25:44 -0000	1.24
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "buffer.h"
-#include "file-lock.h"
 #include "mail-index-view-private.h"
 #include "mail-transaction-log.h"
 

Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- mail-index.c	9 Oct 2004 14:20:21 -0000	1.152
+++ mail-index.c	10 Oct 2004 17:25:44 -0000	1.153
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "buffer.h"
-#include "file-lock.h"
 #include "mmap-util.h"
 #include "read-full.h"
 #include "write-full.h"
@@ -948,7 +947,8 @@
 	return 1;
 }
 
-int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
+		    enum mail_index_lock_method lock_method)
 {
 	int i = 0, ret;
 
@@ -963,6 +963,7 @@
 		index->lock_type = F_UNLCK;
 		index->lock_id = 2;
 
+		index->readonly = FALSE;
 		index->nodiskspace = FALSE;
 		index->index_lock_timeout = FALSE;
 		index->log_locked = FALSE;
@@ -970,9 +971,7 @@
 			(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->lock_method = lock_method;
 
 		ret = mail_index_open_files(index, flags);
 		if (ret <= 0)

Index: mail-index.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.131
retrieving revision 1.132
diff -u -d -r1.131 -r1.132
--- mail-index.h	4 Oct 2004 16:31:51 -0000	1.131
+++ mail-index.h	10 Oct 2004 17:25:44 -0000	1.132
@@ -23,9 +23,13 @@
 	/* Don't try to write() to mmap()ed index files. Required for the few
 	   OSes that don't have unified buffer cache
 	   (currently OpenBSD <= 3.5) */
-	MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE	= 0x08,
-	/* Don't use fcntl() locking */
-	MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE= 0x10
+	MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE	= 0x08
+};
+
+enum mail_index_lock_method {
+	MAIL_INDEX_LOCK_FCNTL,
+	MAIL_INDEX_LOCK_FLOCK,
+	MAIL_INDEX_LOCK_DOTLOCK
 };
 
 enum mail_index_header_compat_flags {
@@ -140,7 +144,8 @@
 void mail_index_set_permissions(struct mail_index *index,
 				mode_t mode, gid_t gid);
 
-int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
+		    enum mail_index_lock_method lock_method);
 void mail_index_close(struct mail_index *index);
 
 /* Force checking if index can be refreshed. */

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- mail-transaction-log.c	8 Oct 2004 17:51:48 -0000	1.62
+++ mail-transaction-log.c	10 Oct 2004 17:25:44 -0000	1.63
@@ -3,7 +3,6 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "buffer.h"
-#include "file-lock.h"
 #include "file-dotlock.h"
 #include "read-full.h"
 #include "write-full.h"
@@ -129,11 +128,11 @@
 	if (file->locked)
 		return 0;
 
-	if (file->log->index->fcntl_locks_disable)
+	if (file->log->index->lock_type == MAIL_INDEX_LOCK_DOTLOCK)
 		return mail_transaction_log_file_dotlock(file);
 
-	ret = file_wait_lock_full(file->fd, F_WRLCK, DEFAULT_LOCK_TIMEOUT,
-				  NULL, NULL);
+	ret = mail_index_lock_fd(file->log->index, file->fd, F_WRLCK,
+				 MAIL_INDEX_LOCK_SECS);
 	if (ret > 0) {
 		file->locked = TRUE;
 		return 0;
@@ -141,7 +140,7 @@
 	if (ret < 0) {
 		mail_index_file_set_syscall_error(file->log->index,
 						  file->filepath,
-						  "file_wait_lock()");
+						  "mail_index_wait_lock_fd()");
 		return -1;
 	}
 
@@ -163,16 +162,16 @@
 
 	file->locked = FALSE;
 
-	if (file->log->index->fcntl_locks_disable) {
+	if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) {
 		mail_transaction_log_file_undotlock(file);
 		return;
 	}
 
-	ret = file_wait_lock(file->fd, F_UNLCK);
+	ret = mail_index_lock_fd(file->log->index, file->fd, F_UNLCK, 0);
 	if (ret <= 0) {
 		mail_index_file_set_syscall_error(file->log->index,
 						  file->filepath,
-						  "file_wait_lock()");
+						  "mail_index_wait_lock_fd()");
 	}
 }
 



More information about the dovecot-cvs mailing list