[dovecot-cvs] dovecot/src/lib-index mail-index.c, 1.188, 1.189 mail-transaction-log-append.c, 1.2, 1.3 mail-transaction-log-view.c, 1.35, 1.36 mail-transaction-log.c, 1.88, 1.89 mail-transaction-log.h, 1.25, 1.26

cras at dovecot.org cras at dovecot.org
Sat Mar 5 14:41:24 EET 2005


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

Modified Files:
	mail-index.c mail-transaction-log-append.c 
	mail-transaction-log-view.c mail-transaction-log.c 
	mail-transaction-log.h 
Log Message:
We could have gone past the transaction log view's boundaries if log was
just rotated. Plus other transaction log cleanups, fixes and new asserts.



Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.188
retrieving revision 1.189
diff -u -d -r1.188 -r1.189
--- mail-index.c	8 Feb 2005 22:44:47 -0000	1.188
+++ mail-index.c	5 Mar 2005 12:41:22 -0000	1.189
@@ -732,7 +732,10 @@
 
 	mail_transaction_log_view_get_prev_pos(log_view, &prev_seq,
 					       &prev_offset);
-        index->map->hdr.log_file_seq = prev_seq;
+	i_assert(prev_seq <= max_seq &&
+		 (prev_seq != max_seq || prev_offset <= max_offset));
+
+	index->map->hdr.log_file_seq = prev_seq;
 	index->map->hdr.log_file_int_offset =
 		index->map->hdr.log_file_ext_offset = prev_offset;
 

Index: mail-transaction-log-append.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-append.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mail-transaction-log-append.c	5 Mar 2005 10:19:37 -0000	1.2
+++ mail-transaction-log-append.c	5 Mar 2005 12:41:22 -0000	1.3
@@ -345,7 +345,7 @@
 
 	if (log->head->sync_offset > MAIL_TRANSACTION_LOG_ROTATE_SIZE &&
 	    (time_t)log->head->hdr.create_stamp <
-	    ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_MIN_TIME) {
+	    ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_TIME) {
 		/* we might want to rotate, but check first that everything is
 		   synced in index. */
 		if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0) {

Index: mail-transaction-log-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- mail-transaction-log-view.c	14 Nov 2004 01:23:21 -0000	1.35
+++ mail-transaction-log-view.c	5 Mar 2005 12:41:22 -0000	1.36
@@ -91,24 +91,19 @@
 	if (min_file_seq == 0) {
 		/* new index, transaction file not synced yet */
 		min_file_seq = 1;
-		min_file_offset = sizeof(struct mail_transaction_log_header);
+		min_file_offset = 0;
 
 		if (max_file_seq == 0) {
 			max_file_seq = min_file_seq;
 			max_file_offset = min_file_offset;
 		}
-	} else if (min_file_offset == 0) {
-		/* this could happen if internal transactions haven't yet been
-		   committed but external are. just assume we're at the
-		   beginning. */
-		min_file_offset = sizeof(struct mail_transaction_log_header);
-	}
+	} 
 
 	if (min_file_seq == view->log->tail->hdr.prev_file_seq &&
 	    min_file_offset == view->log->tail->hdr.prev_file_offset) {
 		/* we can skip this */
 		min_file_seq = view->log->tail->hdr.file_seq;
-		min_file_offset = sizeof(struct mail_transaction_log_header);
+		min_file_offset = 0;
 
 		if (min_file_seq > max_file_seq) {
 			/* empty view */
@@ -127,13 +122,20 @@
 		return -1;
 	}
 
+	if (min_file_offset == 0) {
+		/* this could happen if internal transactions haven't yet been
+		   committed but external are. just assume we're at the
+		   beginning. */
+		min_file_offset = file->hdr.hdr_size;
+		if (max_file_offset == 0 && min_file_seq == max_file_seq)
+			max_file_offset = min_file_offset;
+	}
+
 	/* check these later than others as index file may have corrupted
 	   log_file_offset. we should have recreated the log file and
 	   skipped min_file_seq file above.. max_file_offset can be broken
 	   only if min_file_seq = max_file_seq. */
-	i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
-	i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
-
+	i_assert(min_file_offset >= file->hdr.hdr_size);
 	i_assert(min_file_seq != max_file_seq ||
 		 min_file_offset <= max_file_offset);
 
@@ -167,9 +169,8 @@
 
 		end_offset = file->hdr.file_seq == max_file_seq ?
 			max_file_offset : (uoff_t)-1;
-		ret = mail_transaction_log_file_map(file,
-			sizeof(struct mail_transaction_log_header),
-			end_offset);
+		ret = mail_transaction_log_file_map(file, file->hdr.hdr_size,
+						    end_offset);
 		if (ret == 0) {
 			mail_index_set_error(view->log->index,
 				"Lost transaction log file %s seq %u",
@@ -211,6 +212,8 @@
 	view->max_file_offset = max_file_offset;
 	view->type_mask = type_mask;
 	view->broken = FALSE;
+
+	i_assert(view->cur->hdr.file_seq == min_file_seq);
 	return 0;
 }
 
@@ -258,23 +261,27 @@
 	uint32_t hdr_size;
 	size_t file_size;
 
+	if (view->cur == NULL)
+		return 0;
+
+	view->prev_file_seq = view->cur->hdr.file_seq;
+	view->prev_file_offset = view->cur_offset;
+
 	for (;;) {
 		file = view->cur;
 		if (file == NULL)
 			return 0;
 
-		view->prev_file_seq = file->hdr.file_seq;
-		view->prev_file_offset = view->cur_offset;
-
 		if (view->cur_offset != file->sync_offset)
 			break;
 
 		view->cur = file->next;
-		view->cur_offset = sizeof(struct mail_transaction_log_header);
+		view->cur_offset = file->hdr.hdr_size;
 	}
 
-	if (view->cur_offset >= view->max_file_offset &&
-	    file->hdr.file_seq == view->max_file_seq)
+	if (file->hdr.file_seq > view->max_file_seq ||
+	    (view->cur_offset >= view->max_file_offset &&
+	     file->hdr.file_seq == view->max_file_seq))
 		return 0;
 
 	data = buffer_get_data(file->buffer, &file_size);

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -d -r1.88 -r1.89
--- mail-transaction-log.c	5 Mar 2005 10:25:09 -0000	1.88
+++ mail-transaction-log.c	5 Mar 2005 12:41:22 -0000	1.89
@@ -233,9 +233,12 @@
 	if (index->fd != -1 &&
 	    INDEX_HAS_MISSING_LOGS(index, log->head)) {
 		/* head log file isn't same as head index file -
-		   shouldn't happen except in race conditions. lock them and
-		   check again - FIXME: missing error handling. */
-		(void)mail_transaction_log_check_file_seq(log);
+		   shouldn't happen except in race conditions.
+		   lock them and check again */
+		if (mail_transaction_log_check_file_seq(log) < 0) {
+			mail_transaction_log_close(log);
+			return NULL;
+		}
 	}
 	return log;
 }
@@ -256,6 +259,11 @@
 static void
 mail_transaction_log_file_close(struct mail_transaction_log_file *file)
 {
+	if (file == file->log->head)
+		file->log->head = NULL;
+	if (file == file->log->tail)
+		file->log->tail = file->next;
+
 	mail_transaction_log_file_unlock(file);
 
 	if (file->buffer != NULL)
@@ -340,7 +348,8 @@
 static int
 mail_transaction_log_file_create2(struct mail_transaction_log *log,
 				  const char *path, int fd,
-				  dev_t dev, ino_t ino)
+				  struct dotlock **dotlock,
+				  dev_t dev, ino_t ino, uoff_t file_size)
 {
 	struct mail_index *index = log->index;
 	struct mail_transaction_log_header hdr;
@@ -354,10 +363,11 @@
 		if ((ret = fstat(fd2, &st)) < 0) {
 			mail_index_file_set_syscall_error(index, path,
 							  "fstat()");
-		} else if (st.st_ino == ino && CMP_DEV_T(st.st_dev, dev)) {
+		} else if (st.st_ino == ino && CMP_DEV_T(st.st_dev, dev) &&
+			   (uoff_t)st.st_size == file_size) {
 			/* same file, still broken */
 		} else {
-			(void)file_dotlock_delete(&log->dotlock);
+			(void)file_dotlock_delete(dotlock);
 			return fd2;
 		}
 
@@ -400,31 +410,27 @@
 		return -1;
 	}
 
-	fd2 = dup(fd);
-	if (fd2 < 0) {
-		mail_index_file_set_syscall_error(index, path, "dup()");
-		return -1;
-	}
-
-	if (file_dotlock_replace(&log->dotlock, 0) <= 0)
+	if (file_dotlock_replace(dotlock,
+				 DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) <= 0)
 		return -1;
 
 	/* success */
-	return fd2;
+	return fd;
 }
 
 static int
 mail_transaction_log_file_create(struct mail_transaction_log *log,
-				 const char *path, dev_t dev, ino_t ino)
+				 const char *path,
+				 dev_t dev, ino_t ino, uoff_t file_size)
 {
+	struct dotlock *dotlock;
         mode_t old_mask;
 	int fd, fd2;
 
 	/* With dotlocking we might already have path.lock created, so this
 	   filename has to be different. */
 	old_mask = umask(log->index->mode ^ 0666);
-	fd = file_dotlock_open(&log->new_dotlock_settings, path, 0,
-			       &log->dotlock);
+	fd = file_dotlock_open(&log->new_dotlock_settings, path, 0, &dotlock);
 	umask(old_mask);
 
 	if (fd == -1) {
@@ -436,13 +442,14 @@
 	if (log->index->gid != (gid_t)-1 &&
 	    fchown(fd, (uid_t)-1, log->index->gid) < 0) {
 		mail_index_file_set_syscall_error(log->index, path, "fchown()");
-		(void)file_dotlock_delete(&log->dotlock);
+		(void)file_dotlock_delete(&dotlock);
 		return -1;
 	}
 
-	fd2 = mail_transaction_log_file_create2(log, path, fd, dev, ino);
+	fd2 = mail_transaction_log_file_create2(log, path, fd, &dotlock,
+						dev, ino, file_size);
 	if (fd2 < 0) {
-		(void)file_dotlock_delete(&log->dotlock);
+		(void)file_dotlock_delete(&dotlock);
 		return -1;
 	}
 	return fd2;
@@ -475,8 +482,8 @@
 	ret = mail_transaction_log_file_read_hdr(file);
 	if (ret == 0) {
 		/* corrupted header */
-		fd = mail_transaction_log_file_create(log, path,
-						      st.st_dev, st.st_ino);
+		fd = mail_transaction_log_file_create(log, path, st.st_dev,
+						      st.st_ino, st.st_size);
 		if (fd == -1)
 			ret = -1;
 		else if (fstat(fd, &st) < 0) {
@@ -520,6 +527,8 @@
 			/* log replaced with file having same sequence as
 			   previous one. shouldn't happen unless previous
 			   log file was corrupted.. */
+			file->next = (*p)->next;
+			(*p)->next = NULL;
 			break;
 		}
 	}
@@ -542,7 +551,7 @@
 			return NULL;
 		}
 
-		fd = mail_transaction_log_file_create(log, path, 0, 0);
+		fd = mail_transaction_log_file_create(log, path, 0, 0, 0);
 		if (fd == -1)
 			return NULL;
 	}
@@ -563,9 +572,6 @@
 			*p = next;
 		}
 	}
-
-	if (log->tail == NULL)
-		log->head = NULL;
 }
 
 int mail_transaction_log_rotate(struct mail_transaction_log *log, int lock)
@@ -574,6 +580,8 @@
 	struct stat st;
 	int fd;
 
+	i_assert(log->head->locked);
+
 	if (fstat(log->head->fd, &st) < 0) {
 		mail_index_file_set_syscall_error(log->index,
 						  log->head->filepath,
@@ -582,7 +590,7 @@
 	}
 
 	fd = mail_transaction_log_file_create(log, log->head->filepath,
-					      st.st_dev, st.st_ino);
+					      st.st_dev, st.st_ino, st.st_size);
 	if (fd == -1)
 		return -1;
 
@@ -609,19 +617,6 @@
 	return 0;
 }
 
-static int mail_transaction_log_recreate(struct mail_transaction_log *log)
-{
-	unsigned int lock_id;
-	int ret;
-
-	if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0)
-		return -1;
-
-	ret = mail_transaction_log_rotate(log, FALSE);
-	mail_index_unlock(log->index, lock_id);
-	return ret;
-}
-
 static int mail_transaction_log_refresh(struct mail_transaction_log *log)
 {
         struct mail_transaction_log_file *file;
@@ -632,10 +627,6 @@
 			   MAIL_TRANSACTION_LOG_PREFIX, NULL);
 	if (stat(path, &st) < 0) {
 		mail_index_file_set_syscall_error(log->index, path, "stat()");
-		if (errno == ENOENT && log->head->locked) {
-			/* lost? */
-			return mail_transaction_log_recreate(log);
-		}
 		return -1;
 	}
 

Index: mail-transaction-log.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- mail-transaction-log.h	5 Mar 2005 10:19:37 -0000	1.25
+++ mail-transaction-log.h	5 Mar 2005 12:41:22 -0000	1.26
@@ -7,7 +7,7 @@
 
 #define MAIL_TRANSACTION_LOG_PREFIX ".log"
 #define MAIL_TRANSACTION_LOG_ROTATE_SIZE (1024*128)
-#define MAIL_TRANSACTION_LOG_ROTATE_MIN_TIME (60*5)
+#define MAIL_TRANSACTION_LOG_ROTATE_TIME (60*5)
 
 struct mail_transaction_log_header {
 	uint8_t major_version;



More information about the dovecot-cvs mailing list