[dovecot-cvs] dovecot/src/lib-index mail-cache-private.h, 1.20, 1.21 mail-cache.c, 1.59, 1.60 mail-index-lock.c, 1.38, 1.39 mail-index-private.h, 1.43, 1.44 mail-transaction-log.c, 1.76, 1.77

cras at dovecot.org cras at dovecot.org
Sun Dec 5 06:10:46 EET 2004


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

Modified Files:
	mail-cache-private.h mail-cache.c mail-index-lock.c 
	mail-index-private.h mail-transaction-log.c 
Log Message:
lock_method=dotlock doesn't crash anymore while trying to modify cache file.
We didn't previously deal with any fatal errors that fcntl/flock locking
could have given but assumed that the locking succeeded.



Index: mail-cache-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-private.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- mail-cache-private.h	5 Dec 2004 01:38:17 -0000	1.20
+++ mail-cache-private.h	5 Dec 2004 04:10:43 -0000	1.21
@@ -125,6 +125,7 @@
 	const void *data;
 	size_t mmap_length;
 	struct file_cache *file_cache;
+	struct dotlock dotlock;
 
 	const struct mail_cache_header *hdr;
 	struct mail_cache_header hdr_copy;

Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- mail-cache.c	5 Dec 2004 01:45:53 -0000	1.59
+++ mail-cache.c	5 Dec 2004 04:10:43 -0000	1.60
@@ -299,6 +299,24 @@
 	i_free(cache);
 }
 
+static int mail_cache_lock_file(struct mail_cache *cache, int lock_type)
+{
+	if (cache->index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
+		return mail_index_lock_fd(cache->index, cache->filepath,
+					  cache->fd, lock_type,
+					  MAIL_INDEX_LOCK_SECS);
+	}
+
+	if (lock_type != F_UNLCK) {
+		return file_lock_dotlock(cache->filepath, NULL, FALSE,
+					 MAIL_INDEX_LOCK_SECS, 0,
+					 MAIL_INDEX_LOCK_SECS,
+					 NULL, NULL, &cache->dotlock);
+	} else {
+		return file_unlock_dotlock(cache->filepath, &cache->dotlock);
+	}
+}
+
 int mail_cache_lock(struct mail_cache *cache)
 {
 	struct mail_index_view *view;
@@ -330,13 +348,9 @@
 	}
 
 	for (i = 0; i < 3; i++) {
-		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()");
+		ret = mail_cache_lock_file(cache, F_WRLCK);
+		if (ret <= 0)
 			break;
-		}
 		cache->locked = TRUE;
 
 		if (cache->hdr->file_seq == ext->reset_id) {
@@ -414,10 +428,7 @@
 		mail_cache_update_need_compress(cache);
 	}
 
-	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)");
-	}
+	(void)mail_cache_lock_file(cache, 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.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- mail-index-lock.c	5 Dec 2004 01:45:53 -0000	1.38
+++ mail-index-lock.c	5 Dec 2004 04:10:43 -0000	1.39
@@ -33,10 +33,13 @@
 
 #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)
+int mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
+		       int lock_type, unsigned int timeout_secs)
 {
-	if (timeout_secs != 0) alarm(MAIL_INDEX_LOCK_WAIT_TIME);
+	int ret;
+
+	if (timeout_secs != 0)
+		alarm(MAIL_INDEX_LOCK_WAIT_TIME);
 
 	switch (index->lock_method) {
 	case MAIL_INDEX_LOCK_FCNTL: {
@@ -50,24 +53,28 @@
 		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;
-			}
+		ret = fcntl(fd, timeout_secs ? F_SETLKW : F_SETLK, &fl);
+		if (timeout_secs != 0) alarm(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 (ret == 0)
+			return 1;
+
+		if (timeout_secs == 0 &&
+		    (errno == EACCES || errno == EAGAIN)) {
+			/* locked by another process */
+			return 0;
 		}
-		if (timeout_secs != 0) alarm(0);
-		return 1;
+
+		if (errno == EINTR) {
+			/* most likely alarm hit, meaning we timeouted.
+			   even if not, we probably want to be killed
+			   so stop blocking. */
+			errno = EAGAIN;
+			return 0;
+		}
+		mail_index_file_set_syscall_error(index, path,
+						  "mail_index_lock_fd()");
+		return -1;
 #endif
 	}
 	case MAIL_INDEX_LOCK_FLOCK: {
@@ -88,16 +95,20 @@
 			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;
-			}
-		}
+		ret = flock(fd, operation);
 		if (timeout_secs != 0) alarm(0);
-		return 1;
+
+		if (ret == 0)
+			return 1;
+
+		if (errno == EWOULDBLOCK || errno == EINTR) {
+			/* a) locked by another process,
+			   b) timeouted */
+			return 0;
+		}
+		mail_index_file_set_syscall_error(index, path,
+						  "mail_index_lock_fd()");
+		return -1;
 #endif
 	}
 	case MAIL_INDEX_LOCK_DOTLOCK:
@@ -160,8 +171,8 @@
 	}
 
 	if (lock_type == F_RDLCK || !index->log_locked) {
-		ret = mail_index_lock_fd(index, index->fd, lock_type,
-					 timeout_secs);
+		ret = mail_index_lock_fd(index, index->filepath, 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
@@ -177,14 +188,11 @@
 		   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 = 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;
+		ret = mail_index_lock_fd(index, index->filepath, index->fd,
+					 lock_type, 0);
 	}
+	if (ret <= 0)
+		return ret;
 
 	if (index->lock_type == F_UNLCK)
 		index->lock_id += 2;
@@ -369,10 +377,8 @@
 	if (index->shared_lock_count > 0 &&
 	    index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
 		/* leave ourself shared locked. */
-		if (mail_index_lock_fd(index, index->fd, F_RDLCK, 0) <= 0) {
-			mail_index_file_set_syscall_error(index,
-				index->copy_lock_path, "mail_index_lock_fd()");
-		}
+		(void)mail_index_lock_fd(index, index->filepath, index->fd,
+					 F_RDLCK, 0);
 		i_assert(index->lock_type == F_WRLCK);
 		index->lock_type = F_RDLCK;
 	}
@@ -409,11 +415,8 @@
 		index->lock_id += 2;
 		index->lock_type = F_UNLCK;
 		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,
-					"mail_index_lock_fd()");
-			}
+			(void)mail_index_lock_fd(index, index->filepath,
+						 index->fd, F_UNLCK, 0);
 		}
 	}
 }

Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mail-index-private.h	5 Dec 2004 01:45:53 -0000	1.43
+++ mail-index-private.h	5 Dec 2004 04:10:43 -0000	1.44
@@ -168,8 +168,8 @@
 /* Returns 1 if given lock_id is valid, 0 if not. */
 int mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
 
-int mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
-		       unsigned int timeout_secs);
+int mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
+		       int lock_type, unsigned int timeout_secs);
 
 /* Reopen index file if it has changed. */
 int mail_index_reopen_if_needed(struct mail_index *index);

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- mail-transaction-log.c	4 Dec 2004 21:57:36 -0000	1.76
+++ mail-transaction-log.c	5 Dec 2004 04:10:43 -0000	1.77
@@ -126,8 +126,8 @@
 	if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK)
 		return mail_transaction_log_file_dotlock(file);
 
-	ret = mail_index_lock_fd(file->log->index, file->fd, F_WRLCK,
-				 MAIL_INDEX_LOCK_SECS);
+	ret = mail_index_lock_fd(file->log->index, file->filepath, file->fd,
+				 F_WRLCK, MAIL_INDEX_LOCK_SECS);
 	if (ret > 0) {
 		file->locked = TRUE;
 		return 0;
@@ -162,7 +162,8 @@
 		return;
 	}
 
-	ret = mail_index_lock_fd(file->log->index, file->fd, F_UNLCK, 0);
+	ret = mail_index_lock_fd(file->log->index, file->filepath, file->fd,
+				 F_UNLCK, 0);
 	if (ret <= 0) {
 		mail_index_file_set_syscall_error(file->log->index,
 						  file->filepath,



More information about the dovecot-cvs mailing list