[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.63, 1.64 mail-index-private.h, 1.84, 1.85 mail-index.c, 1.274, 1.275

tss at dovecot.org tss at dovecot.org
Wed May 16 20:07:53 EEST 2007


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

Modified Files:
	mail-index-lock.c mail-index-private.h mail-index.c 
Log Message:
If index file is shared locked while we're trying to exclusively lock it,
don't wait 2 seconds for the lock. Also don't bother copying the index into
a temp file when it's locked, do that only when it's being unlocked so it
doesn't have to be written twice.



Index: mail-index-lock.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- mail-index-lock.c	13 May 2007 23:01:25 -0000	1.63
+++ mail-index-lock.c	16 May 2007 17:07:50 -0000	1.64
@@ -166,7 +166,7 @@
 	return -1;
 }
 
-static int mail_index_copy(struct mail_index *index)
+static int mail_index_copy(struct mail_index *index, const char **path_r)
 {
 	struct mail_index_map *map = index->map;
 	unsigned int base_size;
@@ -195,8 +195,7 @@
 		(void)unlink(path);
 		fd = -1;
 	} else {
-		i_assert(index->copy_lock_path == NULL);
-		index->copy_lock_path = i_strdup(path);
+		*path_r = path;
 	}
 
 	return fd;
@@ -204,48 +203,21 @@
 
 static int mail_index_lock_exclusive_copy(struct mail_index *index)
 {
-	int fd, old_lock_type;
+	struct mail_index_map *map;
 
 	i_assert(index->log_locked);
-
-	if (index->copy_lock_path != NULL) {
-		index->excl_lock_count++;
-		return 0;
-	}
-
         i_assert(index->excl_lock_count == 0);
 
-	/* copy the index to index.tmp and use it */
-	fd = mail_index_copy(index);
-	if (fd == -1) {
-		if (!index->nodiskspace)
-			return -1;
-
-		if (mail_index_move_to_memory(index) < 0)
-			return -1;
-		index->lock_type = F_WRLCK;
-		index->excl_lock_count++;
-		return 0;
-	}
-
-	old_lock_type = index->lock_type;
-	index->lock_type = F_WRLCK;
-
-	if (mail_index_reopen(index, fd) < 0) {
-		(void)close(fd);
-		if (unlink(index->copy_lock_path) < 0) {
-			mail_index_file_set_syscall_error(index,
-							  index->copy_lock_path,
-							  "unlink()");
-		}
-		i_free(index->copy_lock_path);
-		index->copy_lock_path = NULL;
+	map = mail_index_map_clone(index->map, index->map->hdr.record_size);
+	mail_index_unmap(index, &index->map);
+	index->map = map;
+	index->hdr = &map->hdr;
 
-		index->lock_type = old_lock_type;
-		return -1;
-	}
+	map->write_atomic = TRUE;
+	map->write_to_disk = TRUE;
 
 	index->excl_lock_count++;
+	index->lock_type = F_WRLCK;
 	return 0;
 }
 
@@ -275,37 +247,32 @@
 	return 0;
 }
 
-static int mail_index_copy_lock_finish(struct mail_index *index)
+static int
+mail_index_copy_lock_finish(struct mail_index *index, const char *path)
 {
 	int ret = 0;
 
 	if (!index->fsync_disable) {
 		if (fsync(index->fd) < 0) {
-			mail_index_file_set_syscall_error(index,
-							  index->copy_lock_path,
+			mail_index_file_set_syscall_error(index, path,
 							  "fsync()");
 			ret = -1;
 		}
 	}
 
-	if (ret < 0 || MAIL_INDEX_IS_IN_MEMORY(index)) {
-		/* fsync() failed / we've since moved to in-memory indexes */
-		if (unlink(index->copy_lock_path) < 0) {
+	if (ret == 0 && rename(path, index->filepath) < 0) {
+		mail_index_set_error(index, "rename(%s, %s) failed: %m",
+				     path, index->filepath);
+		ret = -1;
+	}
+	if (ret < 0) {
+		if (unlink(path) < 0) {
 			mail_index_set_error(index, "unlink(%s) failed: %m",
-					     index->copy_lock_path);
-		}
-	} else {
-		if (rename(index->copy_lock_path, index->filepath) < 0) {
-			mail_index_set_error(index, "rename(%s, %s) failed: %m",
-					     index->copy_lock_path,
-					     index->filepath);
-			ret = -1;
+					     path);
 		}
+		return -1;
 	}
-
-	i_free(index->copy_lock_path);
-	index->copy_lock_path = NULL;
-	return ret;
+	return 0;
 }
 
 static int mail_index_write_map_over(struct mail_index *index)
@@ -342,14 +309,17 @@
 	return 0;
 }
 
-static int mail_index_copy_and_reopen(struct mail_index *index)
+static int
+mail_index_copy_and_reopen(struct mail_index *index, const char **path_r)
 {
+	const char *path = NULL;
 	int fd;
 
-	fd = mail_index_copy(index);
+	fd = mail_index_copy(index, &path);
 	if (fd == -1) {
 		if (!index->nodiskspace)
 			return -1;
+
 		return mail_index_move_to_memory(index);
 	}
 
@@ -357,27 +327,21 @@
 		(void)close(fd);
 		return -1;
 	}
+	*path_r = path;
 	return 0;
 }
 
-static void mail_index_write_map(struct mail_index *index)
+static void
+mail_index_write_map(struct mail_index *index, const char **path_r)
 {
 	struct mail_index_map *map = index->map;
 
-	if (map->write_atomic || index->copy_lock_path != NULL ||
-	    index->fd == -1) {
+	if (map->write_atomic || index->fd == -1) {
 		/* write by recreating the index */
 		i_assert(index->log_locked);
 
-		if (index->copy_lock_path != NULL) {
-			/* new mapping replaces the old */
-			(void)unlink(index->copy_lock_path);
-			i_free(index->copy_lock_path);
-			index->copy_lock_path = NULL;
-		}
-
 		if (!MAIL_INDEX_IS_IN_MEMORY(index)) {
-			if (mail_index_copy_and_reopen(index) < 0)
+			if (mail_index_copy_and_reopen(index, path_r) < 0)
 				mail_index_set_inconsistent(index);
 		}
 
@@ -398,8 +362,10 @@
 
 static bool mail_index_excl_unlock_finish(struct mail_index *index)
 {
+	const char *path = NULL;
+
 	if (index->map != NULL && index->map->write_to_disk)
-		mail_index_write_map(index);
+		mail_index_write_map(index, &path);
 
 	if (index->shared_lock_count > 0 &&
 	    index->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
@@ -411,10 +377,10 @@
 			(void)file_lock_try_update(index->file_lock, F_RDLCK);
 	}
 
-	if (index->copy_lock_path != NULL) {
+	if (path != NULL) {
 		i_assert(index->log_locked);
 
-		if (mail_index_copy_lock_finish(index) < 0)
+		if (mail_index_copy_lock_finish(index, path) < 0)
 			mail_index_set_inconsistent(index);
 
 		/* We may still have shared locks for the old file, but they
@@ -443,6 +409,7 @@
 		/* exclusive lock */
 		i_assert(lock_id == index->lock_id + 1);
 		i_assert(index->excl_lock_count > 0);
+		i_assert(index->lock_type == F_WRLCK);
 		if (--index->excl_lock_count == 0)
 			unlock = mail_index_excl_unlock_finish(index);
 	}

Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- mail-index-private.h	16 May 2007 15:25:29 -0000	1.84
+++ mail-index-private.h	16 May 2007 17:07:50 -0000	1.85
@@ -162,7 +162,6 @@
 
 	int lock_type, shared_lock_count, excl_lock_count;
 	unsigned int lock_id;
-	char *copy_lock_path;
 	enum file_lock_method lock_method;
 
 	struct file_lock *file_lock;

Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.274
retrieving revision 1.275
diff -u -d -r1.274 -r1.275
--- mail-index.c	16 May 2007 15:25:29 -0000	1.274
+++ mail-index.c	16 May 2007 17:07:50 -0000	1.275
@@ -1707,7 +1707,6 @@
 		index->fd = -1;
 	}
 
-	i_free_and_null(index->copy_lock_path);
 	i_free_and_null(index->filepath);
 
 	index->indexid = 0;
@@ -1797,8 +1796,6 @@
 {
 	struct stat st1, st2;
 
-        i_assert(index->copy_lock_path == NULL);
-
 	if (MAIL_INDEX_IS_IN_MEMORY(index))
 		return 0;
 



More information about the dovecot-cvs mailing list