[dovecot-cvs] dovecot/src/lib-index mail-index.c, 1.230.2.20, 1.230.2.21 mail-transaction-log.c, 1.111.2.13, 1.111.2.14 mail-transaction-log.h, 1.31, 1.31.2.1

tss at dovecot.org tss at dovecot.org
Thu Mar 8 22:02:36 EET 2007


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

Modified Files:
      Tag: branch_1_0
	mail-index.c mail-transaction-log.c mail-transaction-log.h 
Log Message:
If index file is corrupted, recreate transaction log file instead of trying
to reuse it.



Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.230.2.20
retrieving revision 1.230.2.21
diff -u -d -r1.230.2.20 -r1.230.2.21
--- mail-index.c	6 Mar 2007 19:11:25 -0000	1.230.2.20
+++ mail-index.c	8 Mar 2007 20:02:33 -0000	1.230.2.21
@@ -1543,7 +1543,7 @@
 	struct mail_index_header hdr;
 	unsigned int lock_id = 0;
 	int ret;
-	bool created = FALSE;
+	bool create = FALSE, created = FALSE;
 
 	ret = mail_index_try_open(index, &lock_id);
 	if (ret > 0)
@@ -1555,12 +1555,15 @@
 			return 0;
 		mail_index_header_init(&hdr);
 		index->hdr = &hdr;
+		create = TRUE;
 	} else if (ret < 0)
 		return -1;
 
 	index->indexid = hdr.indexid;
 
-	index->log = mail_transaction_log_open_or_create(index);
+	index->log = create ?
+		mail_transaction_log_create(index) :
+		mail_transaction_log_open_or_create(index);
 	if (index->log == NULL) {
 		if (ret == 0)
 			index->hdr = NULL;

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.111.2.13
retrieving revision 1.111.2.14
diff -u -d -r1.111.2.13 -r1.111.2.14
--- mail-transaction-log.c	7 Mar 2007 00:47:52 -0000	1.111.2.13
+++ mail-transaction-log.c	8 Mar 2007 20:02:33 -0000	1.111.2.14
@@ -31,6 +31,12 @@
 static struct mail_transaction_log_file *
 mail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
 					 const char *path);
+static struct mail_transaction_log_file *
+mail_transaction_log_file_alloc_in_memory(struct mail_transaction_log *log);
+static int
+mail_transaction_log_file_create(struct mail_transaction_log_file *file,
+				 bool lock, dev_t dev, ino_t ino,
+				 uoff_t file_size);
 static int
 mail_transaction_log_file_read(struct mail_transaction_log_file *file,
 			       uoff_t offset);
@@ -65,6 +71,62 @@
 	}
 }
 
+static struct mail_transaction_log_file *
+mail_transaction_log_file_alloc(struct mail_transaction_log *log,
+				const char *path)
+{
+	struct mail_transaction_log_file *file;
+
+	file = i_new(struct mail_transaction_log_file, 1);
+	file->log = log;
+	file->filepath = i_strdup(path);
+	file->fd = -1;
+	return file;
+}
+
+static void
+mail_transaction_log_file_free(struct mail_transaction_log_file *file)
+{
+	struct mail_transaction_log_file **p;
+	int old_errno = errno;
+
+	mail_transaction_log_file_unlock(file);
+
+	for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
+		if (*p == file) {
+			*p = file->next;
+			break;
+		}
+	}
+
+	if (file == file->log->head)
+		file->log->head = NULL;
+
+	if (file->buffer != NULL) 
+		buffer_free(file->buffer);
+
+	if (file->mmap_base != NULL) {
+		if (munmap(file->mmap_base, file->mmap_size) < 0) {
+			mail_index_file_set_syscall_error(file->log->index,
+							  file->filepath,
+							  "munmap()");
+		}
+	}
+
+	if (file->fd != -1) {
+		if (close(file->fd) < 0) {
+			mail_index_file_set_syscall_error(file->log->index,
+							  file->filepath,
+							  "close()");
+		}
+	}
+
+	i_free(file->filepath);
+        i_free(file);
+
+        errno = old_errno;
+}
+
 static int
 mail_transaction_log_file_dotlock(struct mail_transaction_log_file *file)
 {
@@ -220,10 +282,11 @@
 	return ret;
 }
 
-struct mail_transaction_log *
-mail_transaction_log_open_or_create(struct mail_index *index)
+static struct mail_transaction_log *
+mail_transaction_log_open_int(struct mail_index *index, bool create)
 {
 	struct mail_transaction_log *log;
+	struct mail_transaction_log_file *file;
 	const char *path;
 
 	log = i_new(struct mail_transaction_log, 1);
@@ -236,19 +299,37 @@
 	log->new_dotlock_settings = log->dotlock_settings;
 	log->new_dotlock_settings.lock_suffix = LOG_NEW_DOTLOCK_SUFFIX;
 
-	path = t_strconcat(log->index->filepath,
+	path = t_strconcat(index->filepath,
 			   MAIL_TRANSACTION_LOG_SUFFIX, NULL);
-	log->head = mail_transaction_log_file_open_or_create(log, path);
-	if (log->head == NULL) {
+	if (MAIL_INDEX_IS_IN_MEMORY(index))
+		file = mail_transaction_log_file_alloc_in_memory(log);
+	else if (create) {
+		struct stat st;
+
+		file = mail_transaction_log_file_alloc(log, path);
+		if (stat(path, &st) < 0)
+			memset(&st, 0, sizeof(st));
+		if (mail_transaction_log_file_create(file, FALSE,
+						     st.st_dev, st.st_ino,
+						     st.st_size) < 0) {
+			mail_transaction_log_file_free(file);
+			file = NULL;
+		}
+	} else {
+		file = mail_transaction_log_file_open_or_create(log, path);
+	}
+
+	if (file == NULL) {
 		/* fallback to in-memory indexes */
 		if (mail_index_move_to_memory(index) < 0) {
 			mail_transaction_log_close(&log);
 			return NULL;
 		}
-		log->head = mail_transaction_log_file_open_or_create(log, path);
-		i_assert(log->head != NULL);
+		file = mail_transaction_log_file_open_or_create(log, path);
+		i_assert(file != NULL);
 	}
-	log->head->refcount++;
+	file->refcount++;
+	log->head = file;
 
 	if (index->fd != -1 &&
 	    INDEX_HAS_MISSING_LOGS(index, log->head)) {
@@ -263,6 +344,18 @@
 	return log;
 }
 
+struct mail_transaction_log *
+mail_transaction_log_open_or_create(struct mail_index *index)
+{
+	return mail_transaction_log_open_int(index, FALSE);
+}
+
+struct mail_transaction_log *
+mail_transaction_log_create(struct mail_index *index)
+{
+	return mail_transaction_log_open_int(index, TRUE);
+}
+
 void mail_transaction_log_close(struct mail_transaction_log **_log)
 {
 	struct mail_transaction_log *log = *_log;
@@ -279,49 +372,6 @@
 	i_free(log);
 }
 
-static void
-mail_transaction_log_file_free(struct mail_transaction_log_file *file)
-{
-	struct mail_transaction_log_file **p;
-	int old_errno = errno;
-
-	mail_transaction_log_file_unlock(file);
-
-	for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
-		if (*p == file) {
-			*p = file->next;
-			break;
-		}
-	}
-
-	if (file == file->log->head)
-		file->log->head = NULL;
-
-	if (file->buffer != NULL) 
-		buffer_free(file->buffer);
-
-	if (file->mmap_base != NULL) {
-		if (munmap(file->mmap_base, file->mmap_size) < 0) {
-			mail_index_file_set_syscall_error(file->log->index,
-							  file->filepath,
-							  "munmap()");
-		}
-	}
-
-	if (file->fd != -1) {
-		if (close(file->fd) < 0) {
-			mail_index_file_set_syscall_error(file->log->index,
-							  file->filepath,
-							  "close()");
-		}
-	}
-
-	i_free(file->filepath);
-        i_free(file);
-
-        errno = old_errno;
-}
-
 int mail_transaction_log_move_to_memory(struct mail_transaction_log *log)
 {
 	struct mail_transaction_log_file *file = log->head;
@@ -688,19 +738,6 @@
 	*p = file;
 }
 
-static struct mail_transaction_log_file *
-mail_transaction_log_file_alloc(struct mail_transaction_log *log,
-				const char *path)
-{
-	struct mail_transaction_log_file *file;
-
-	file = i_new(struct mail_transaction_log_file, 1);
-	file->log = log;
-	file->filepath = i_strdup(path);
-	file->fd = -1;
-	return file;
-}
-
 static int
 mail_transaction_log_file_fd_open(struct mail_transaction_log_file *file,
 				  bool head, bool ignore_estale)

Index: mail-transaction-log.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.31
retrieving revision 1.31.2.1
diff -u -d -r1.31 -r1.31.2.1
--- mail-transaction-log.h	14 Jan 2006 18:47:35 -0000	1.31
+++ mail-transaction-log.h	8 Mar 2007 20:02:33 -0000	1.31.2.1
@@ -107,6 +107,8 @@
 
 struct mail_transaction_log *
 mail_transaction_log_open_or_create(struct mail_index *index);
+struct mail_transaction_log *
+mail_transaction_log_create(struct mail_index *index);
 void mail_transaction_log_close(struct mail_transaction_log **log);
 
 int mail_transaction_log_move_to_memory(struct mail_transaction_log *log);



More information about the dovecot-cvs mailing list