[dovecot-cvs] dovecot/src/lib-index/maildir maildir-sync.c,1.36,1.37 maildir-uidlist.c,1.1,1.2 maildir-uidlist.h,1.1,1.2

cras at procontrol.fi cras at procontrol.fi
Mon Apr 21 17:42:02 EEST 2003


Update of /home/cvs/dovecot/src/lib-index/maildir
In directory danu:/tmp/cvs-serv12707/lib-index/maildir

Modified Files:
	maildir-sync.c maildir-uidlist.c maildir-uidlist.h 
Log Message:
Use mtime to check changes in dovecot-uidlist file rather than inode changes
which aren't reliable.



Index: maildir-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-sync.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- maildir-sync.c	16 Apr 2003 15:13:24 -0000	1.36
+++ maildir-sync.c	21 Apr 2003 13:42:00 -0000	1.37
@@ -197,6 +197,16 @@
 			return FALSE;
 		}
 
+		if (uid_rec.uid > uid &&
+		    (hash_rec->action == MAILDIR_FILE_ACTION_UPDATE_FLAGS ||
+		     hash_rec->action == MAILDIR_FILE_ACTION_NONE)) {
+			/* it's UID has changed */
+			hash_rec->action = MAILDIR_FILE_ACTION_UPDATE_CONTENT;
+
+			/* make sure filename is not invalidated by expunge */
+			hash_insert(files, p_strdup(pool, fname), hash_rec);
+		}
+
 		switch (hash_rec->action) {
 		case MAILDIR_FILE_ACTION_EXPUNGE:
 			if (!index->expunge(index, rec, seq, TRUE))
@@ -247,7 +257,14 @@
 			i_assert(hash_rec->action == MAILDIR_FILE_ACTION_NEW);
 
 			/* make sure we set the same UID for it. */
-			i_assert(index->header->next_uid <= uid_rec.uid);
+			if (index->header->next_uid > uid_rec.uid) {
+				index_set_corrupted(index,
+						    "index.next_uid (%u) > "
+						    "uid_rec.uid (%u)",
+						    index->header->next_uid,
+						    uid_rec.uid);
+				return FALSE;
+			}
 			index->header->next_uid = uid_rec.uid;
 
                         hash_rec->action = MAILDIR_FILE_ACTION_NONE;
@@ -428,7 +445,7 @@
 	struct utimbuf ut;
 	struct maildir_uidlist *uidlist;
 	const char *uidlist_path, *cur_dir, *new_dir;
-	time_t index_mtime;
+	time_t index_mtime, uidlist_mtime;
 	int cur_changed;
 
 	*uidlist_r = uidlist = NULL;
@@ -456,12 +473,13 @@
 
 		memset(&st, 0, sizeof(st));
 		cur_changed = TRUE;
+                uidlist_mtime = 0;
 	} else {
-		/* FIXME: save device and inode into index header, so we don't
+		/* FIXME: save mtime into index header, so we don't
 		   have to read it every time mailbox is opened */
+                uidlist_mtime = st.st_mtime;
 		cur_changed = index_mtime != std.st_mtime ||
-			st.st_ino != index->uidlist_ino ||
-			!CMP_DEV_T(st.st_dev, index->uidlist_dev);
+			index->uidlist_mtime != uidlist_mtime;
 	}
 
 	if (new_dirp != NULL || cur_changed) {
@@ -556,18 +574,12 @@
 			return TRUE;
 		}
 
-		if (fstat(index->maildir_lock_fd, &st) < 0) {
-			return index_file_set_syscall_error(index, uidlist_path,
-							    "fstat()");
-		}
-
-		if (!maildir_uidlist_rewrite(index))
+		if (!maildir_uidlist_rewrite(index, &uidlist_mtime))
 			return FALSE;
 	}
 
 	/* uidlist file synced */
-	index->uidlist_ino = st.st_ino;
-	index->uidlist_dev = st.st_dev;
+	index->uidlist_mtime = uidlist_mtime;
 
 	/* update sync stamp */
 	index->file_sync_stamp = std.st_mtime;

Index: maildir-uidlist.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-uidlist.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- maildir-uidlist.c	9 Apr 2003 20:10:01 -0000	1.1
+++ maildir-uidlist.c	21 Apr 2003 13:42:00 -0000	1.2
@@ -12,6 +12,7 @@
 
 #include <stdio.h>
 #include <sys/stat.h>
+#include <utime.h>
 
 /* how many seconds to wait before overriding uidlist.lock */
 #define UIDLIST_LOCK_STALE_TIMEOUT (60*5)
@@ -168,23 +169,14 @@
 	i_free(uidlist);
 }
 
-int maildir_uidlist_rewrite(struct mail_index *index)
+static int maildir_uidlist_rewrite_fd(struct mail_index *index,
+				      const char *temp_path, time_t *mtime)
 {
 	struct mail_index_record *rec;
-	const char *temp_path, *db_path, *p, *fname;
+	struct utimbuf ut;
+	const char *p, *fname;
 	string_t *str;
 	size_t len;
-	int failed = FALSE;
-
-	i_assert(INDEX_IS_UIDLIST_LOCKED(index));
-
-	if (index->lock_type == MAIL_LOCK_UNLOCK) {
-		if (!index->set_lock(index, MAIL_LOCK_SHARED))
-			return FALSE;
-	}
-
-	temp_path = t_strconcat(index->mailbox_path,
-				"/" MAILDIR_UIDLIST_NAME ".lock", NULL);
 
 	str = t_str_new(4096);
 	str_printfa(str, "1 %u %u\n",
@@ -194,7 +186,7 @@
 	while (rec != NULL) {
 		fname = maildir_get_location(index, rec);
 		if (fname == NULL)
-			break;
+			return FALSE;
 
 		p = strchr(fname, ':');
 		len = p == NULL ? strlen(fname) : (size_t)(p-fname);
@@ -205,7 +197,7 @@
 				       str_data(str), str_len(str)) < 0) {
 				index_file_set_syscall_error(index, temp_path,
 							     "write_full()");
-				break;
+				return FALSE;
 			}
 			str_truncate(str, 0);
 		}
@@ -220,20 +212,47 @@
 	if (write_full(index->maildir_lock_fd,
 		       str_data(str), str_len(str)) < 0) {
 		index_file_set_syscall_error(index, temp_path, "write_full()");
-		failed = TRUE;
+		return FALSE;
 	}
 
-	if (fdatasync(index->maildir_lock_fd) < 0) {
-		index_file_set_syscall_error(index, temp_path, "fdatasync()");
-		failed = TRUE;
+	/* uidlist's mtime must grow every time */
+	*mtime = ioloop_time > *mtime ? ioloop_time : *mtime + 1;
+	ut.actime = ioloop_time;
+	ut.modtime = *mtime;
+	if (utime(temp_path, &ut) < 0)
+		index_set_syscall_error(index, "utime()");
+
+	if (fsync(index->maildir_lock_fd) < 0) {
+		index_file_set_syscall_error(index, temp_path, "fsync()");
+		return FALSE;
 	}
+
+	return TRUE;
+}
+
+int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime)
+{
+	const char *temp_path, *db_path;
+	int failed = FALSE;
+
+	i_assert(INDEX_IS_UIDLIST_LOCKED(index));
+
+	if (index->lock_type == MAIL_LOCK_UNLOCK) {
+		if (!index->set_lock(index, MAIL_LOCK_SHARED))
+			return FALSE;
+	}
+
+	temp_path = t_strconcat(index->mailbox_path,
+				"/" MAILDIR_UIDLIST_NAME ".lock", NULL);
+
+	failed = !maildir_uidlist_rewrite_fd(index, temp_path, mtime);
 	if (close(index->maildir_lock_fd) < 0) {
 		index_file_set_syscall_error(index, temp_path, "close()");
 		failed = TRUE;
 	}
         index->maildir_lock_fd = -1;
 
-	if (rec == NULL) {
+	if (!failed) {
 		db_path = t_strconcat(index->mailbox_path,
 				      "/" MAILDIR_UIDLIST_NAME, NULL);
 

Index: maildir-uidlist.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-uidlist.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- maildir-uidlist.h	9 Apr 2003 20:10:01 -0000	1.1
+++ maildir-uidlist.h	21 Apr 2003 13:42:00 -0000	1.2
@@ -22,7 +22,7 @@
 
 int maildir_uidlist_try_lock(struct mail_index *index);
 void maildir_uidlist_unlock(struct mail_index *index);
-int maildir_uidlist_rewrite(struct mail_index *index);
+int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime);
 
 struct maildir_uidlist *maildir_uidlist_open(struct mail_index *index);
 void maildir_uidlist_close(struct maildir_uidlist *uidlist);




More information about the dovecot-cvs mailing list