[dovecot-cvs] dovecot/src/lib-index/maildir Makefile.am,1.7,1.8 maildir-build.c,1.23,1.24 maildir-expunge.c,1.3,1.4 maildir-index.c,1.33,1.34 maildir-index.h,1.23,1.24 maildir-open.c,1.16,1.17 maildir-sync.c,1.58,1.59 maildir-uidlist.c,1.8,1.9 maildir-update-flags.c,1.6,1.7 maildir-rebuild.c,1.16,NONE

cras at procontrol.fi cras at procontrol.fi
Thu Aug 7 00:16:04 EEST 2003


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

Modified Files:
	Makefile.am maildir-build.c maildir-expunge.c maildir-index.c 
	maildir-index.h maildir-open.c maildir-sync.c 
	maildir-uidlist.c maildir-update-flags.c 
Removed Files:
	maildir-rebuild.c 
Log Message:
Index cache file rewrite. It's not finished yet and mbox support is
completely broken. But it's getting difficult to maintain outside cvs :)



Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am	18 May 2003 12:26:06 -0000	1.7
+++ Makefile.am	6 Aug 2003 20:15:32 -0000	1.8
@@ -12,7 +12,6 @@
 	maildir-clean.c \
 	maildir-expunge.c \
 	maildir-open.c \
-	maildir-rebuild.c \
 	maildir-sync.c \
 	maildir-uidlist.c \
 	maildir-update-flags.c

Index: maildir-build.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-build.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- maildir-build.c	18 May 2003 12:26:06 -0000	1.23
+++ maildir-build.c	6 Aug 2003 20:15:32 -0000	1.24
@@ -1,51 +1,27 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
-#include "istream.h"
 #include "maildir-index.h"
-#include "mail-index-util.h"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-static int maildir_record_update(struct mail_index *index,
-				 struct mail_index_update *update, int fd)
-{
-	struct istream *input;
-        enum mail_data_field cache_fields;
-
-	if (index->mail_read_mmaped) {
-		input = i_stream_create_mmap(fd, system_pool,
-					     MAIL_MMAP_BLOCK_SIZE, 0, 0, FALSE);
-	} else {
-		input = i_stream_create_file(fd, system_pool,
-					     MAIL_READ_BLOCK_SIZE, FALSE);
-	}
-
-	cache_fields = index->header->cache_fields & ~DATA_FIELD_LOCATION;
-	mail_index_update_headers(update, input, cache_fields, NULL, NULL);
-
-	i_stream_unref(input);
-	return TRUE;
-}
+#include "mail-cache.h"
 
-static int maildir_index_append_fd(struct mail_index *index,
-				   int fd, const char *fname, int new_dir)
+int maildir_index_append_file(struct mail_cache_transaction_ctx **trans_ctx,
+			      struct mail_index *index, const char *fname,
+			      int new_dir)
 {
 	struct mail_index_record *rec;
-	struct mail_index_update *update;
-	struct stat st;
+        enum mail_index_record_flag index_flags;
 	uoff_t virtual_size;
 	const char *p;
-	int failed;
 
-	i_assert(fname != NULL);
+	i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
 
-	if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
-		return FALSE;
+	if (*trans_ctx == NULL) {
+		if (mail_cache_transaction_begin(index->cache,
+						 TRUE, trans_ctx) <= 0)
+			return FALSE;
+	}
 
-	rec = index->append_begin(index);
+	rec = index->append(index);
 	if (rec == NULL)
 		return FALSE;
 
@@ -53,7 +29,11 @@
 	rec->msg_flags = maildir_filename_get_flags(fname, 0);
 	mail_index_mark_flag_changes(index, rec, 0, rec->msg_flags);
 
-	update = index->update_begin(index, rec);
+	/* always set index flags */
+	index_flags = new_dir ? MAIL_INDEX_FLAG_MAILDIR_NEW : 0;
+	if (!mail_cache_add(*trans_ctx, rec, MAIL_CACHE_INDEX_FLAGS,
+			    &index_flags, sizeof(index_flags)))
+		return FALSE;
 
 	/* set virtual size if found from file name */
 	p = strstr(fname, ",W=");
@@ -65,66 +45,19 @@
 			p++;
 		}
 
-		if (*p == ':' || *p == ',' || *p == '\0') {
-			index->update_field_raw(update, DATA_HDR_VIRTUAL_SIZE,
-						&virtual_size,
-						sizeof(virtual_size));
+		if (*p == ':' || *p == ',' || *p != '\0') {
+			if (!mail_cache_add(*trans_ctx, rec,
+					    MAIL_CACHE_VIRTUAL_FULL_SIZE,
+					    &virtual_size,
+					    sizeof(virtual_size)))
+				return FALSE;
 		}
 	}
 
-	/* set internal date */
-	if (fd != -1 && fstat(fd, &st) == 0) {
-		index->update_field_raw(update, DATA_HDR_INTERNAL_DATE,
-					&st.st_mtime, sizeof(st.st_mtime));
-	}
-
-	/* set the location */
-	if (new_dir)
-		rec->index_flags |= INDEX_MAIL_FLAG_MAILDIR_NEW;
-	index->update_field(update, DATA_FIELD_LOCATION, fname,
-			    MAILDIR_LOCATION_EXTRA_SPACE);
-
-	/* parse the header and update record's fields */
-	failed = fd == -1 ? FALSE : !maildir_record_update(index, update, fd);
-
-	if (!index->update_end(update) || failed) {
-		index->append_abort(index, rec);
+	/* always set location */
+	if (!mail_cache_add(*trans_ctx, rec, MAIL_CACHE_LOCATION,
+			    fname, strlen(fname)+1))
 		return FALSE;
-	}
-
-	return index->append_end(index, rec);
-}
 
-int maildir_index_append_file(struct mail_index *index, const char *dir,
-			      const char *fname, int new_dir)
-{
-	const char *path;
-	int fd, ret;
-
-	i_assert(index->lock_type != MAIL_LOCK_SHARED);
-
-	if ((index->header->cache_fields & ~DATA_FIELD_LOCATION) == 0) {
-		/* nothing cached, don't bother opening the file */
-		return maildir_index_append_fd(index, -1, fname, new_dir);
-	}
-
-	path = t_strconcat(dir, "/", fname, NULL);
-	fd = open(path, O_RDONLY);
-	if (fd == -1) {
-		if (errno == ENOENT) {
-			/* it's not found because it's deleted or renamed.
-			   don't try to handle any error cases here, just
-			   save the thing and let the syncing handle it
-			   later */
-			return maildir_index_append_fd(index, -1,
-						       fname, new_dir);
-		}
-
-		return index_file_set_syscall_error(index, path, "open()");
-	}
-
-	ret = maildir_index_append_fd(index, fd, fname, new_dir);
-	if (close(fd) < 0)
-		return index_file_set_syscall_error(index, path, "close()");
-	return ret;
+	return TRUE;
 }

Index: maildir-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-expunge.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- maildir-expunge.c	15 Jun 2003 02:20:52 -0000	1.3
+++ maildir-expunge.c	6 Aug 2003 20:15:32 -0000	1.4
@@ -12,8 +12,9 @@
 				     const char **fname)
 {
 	const char *path;
+	int new_dir;
 
-	*fname = maildir_get_location(index, rec);
+	*fname = maildir_get_location(index, rec, &new_dir);
 	if (*fname == NULL)
 		return -1;
 
@@ -23,7 +24,7 @@
 	if (index->next_dirty_flush != 0)
 		index->next_dirty_flush = ioloop_time;
 
-	if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+	if (new_dir) {
 		/* probably in new/ dir */
 		path = t_strconcat(index->mailbox_path, "/new/", *fname, NULL);
 		if (unlink(path) == 0)

Index: maildir-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-index.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- maildir-index.c	26 Jun 2003 16:10:33 -0000	1.33
+++ maildir-index.c	6 Aug 2003 20:15:32 -0000	1.34
@@ -6,8 +6,8 @@
 #include "hostpid.h"
 #include "str.h"
 #include "maildir-index.h"
-#include "mail-index-data.h"
 #include "mail-index-util.h"
+#include "mail-cache.h"
 
 #include <stdio.h>
 #include <sys/stat.h>
@@ -24,20 +24,39 @@
 }
 
 const char *maildir_get_location(struct mail_index *index,
-				 struct mail_index_record *rec)
+				 struct mail_index_record *rec, int *new_dir)
 {
 	const char *fname, *new_fname;
 
-	fname = index->lookup_field(index, rec, DATA_FIELD_LOCATION);
+	if (new_dir != NULL)
+		*new_dir = FALSE;
+
+	if (index->new_filenames != NULL) {
+		/* this has the most up-to-date filename */
+		new_fname = hash_lookup(index->new_filenames,
+					POINTER_CAST(rec->uid));
+		if (new_fname != NULL) {
+			if (*new_fname == '/') {
+				new_fname++;
+				if (new_dir != NULL)
+					*new_dir = TRUE;
+			}
+			return new_fname;
+		}
+	}
+
+	/* index file should give us at least the base name. */
+	fname = mail_cache_lookup_string_field(index->cache, rec,
+					       MAIL_CACHE_LOCATION);
 	if (fname == NULL) {
-		index_data_set_corrupted(index->data,
+		mail_cache_set_corrupted(index->cache,
 			"Missing location field for record %u", rec->uid);
+		return NULL;
 	}
 
-	if (index->new_filenames != NULL) {
-		new_fname = hash_lookup(index->new_filenames, fname);
-		if (new_fname != NULL)
-			return new_fname;
+	if (new_dir != NULL) {
+		*new_dir = (mail_cache_get_index_flags(index->cache, rec) &
+			    MAIL_INDEX_FLAG_MAILDIR_NEW) != 0;
 	}
 
 	return fname;
@@ -213,6 +232,31 @@
 	return str_c(flags_str);
 }
 
+void maildir_index_update_filename(struct mail_index *index, unsigned int uid,
+				   const char *fname, int new_dir)
+{
+	const char *new_fname, *old_fname;
+
+	if (index->new_filename_pool == NULL) {
+		index->new_filename_pool =
+			pool_alloconly_create("Maildir filenames", 10240);
+	}
+	if (index->new_filenames == NULL) {
+		index->new_filenames =
+			hash_create(system_pool, index->new_filename_pool, 0,
+				    NULL, NULL);
+	}
+
+	t_push();
+	new_fname = !new_dir ? fname : t_strconcat("/", fname, NULL);
+	old_fname = hash_lookup(index->new_filenames, POINTER_CAST(uid));
+	if (old_fname == NULL || strcmp(old_fname, new_fname) != 0) {
+		hash_insert(index->new_filenames, POINTER_CAST(uid),
+                            p_strdup(index->new_filename_pool, new_fname));
+	}
+	t_pop();
+}
+
 struct mail_index *
 maildir_index_alloc(const char *maildir, const char *index_dir,
 		    const char *control_dir)
@@ -247,18 +291,19 @@
 	i_free(index);
 }
 
-static int maildir_get_internal_date_file(struct mail_index *index,
+static int maildir_get_received_date_file(struct mail_index *index,
 					  struct mail_index_record *rec,
 					  const char **fname, struct stat *st)
 {
 	const char *path;
+	int new_dir;
 
 	/* stat() gives it */
-	*fname = maildir_get_location(index, rec);
+	*fname = maildir_get_location(index, rec, &new_dir);
 	if (*fname == NULL)
 		return -1;
 
-	if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+	if (new_dir) {
 		/* probably in new/ dir */
 		path = t_strconcat(index->mailbox_path, "/new/", *fname, NULL);
 		if (stat(path, st) < 0 && errno != ENOENT) {
@@ -279,7 +324,7 @@
 	return TRUE;
 }
 
-static time_t maildir_get_internal_date(struct mail_index *index,
+static time_t maildir_get_received_date(struct mail_index *index,
 					struct mail_index_record *rec)
 {
 	struct stat st;
@@ -288,11 +333,12 @@
 	int ret, i, found;
 
 	/* try getting it from cache */
-	date = mail_get_internal_date(index, rec);
-	if (date != (time_t)-1)
+	if (mail_cache_copy_fixed_field(index->cache, rec,
+					MAIL_CACHE_RECEIVED_DATE,
+					&date, sizeof(date)))
 		return date;
 
-	ret = maildir_get_internal_date_file(index, rec, &fname, &st);
+	ret = maildir_get_received_date_file(index, rec, &fname, &st);
 	for (i = 0; ret == 0 && i < 10; i++) {
 		/* file is either renamed or deleted. sync the maildir and
 		   see which one. if file appears to be renamed constantly,
@@ -305,7 +351,7 @@
 			return (time_t)-1;
 		}
 
-		ret = maildir_get_internal_date_file(index, rec, &fname, &st);
+		ret = maildir_get_received_date_file(index, rec, &fname, &st);
 	}
 
 	return st.st_mtime;
@@ -317,28 +363,18 @@
 	mail_index_set_lock,
 	mail_index_try_lock,
         mail_index_set_lock_notify_callback,
-	maildir_index_rebuild,
+	mail_index_rebuild,
 	mail_index_fsck,
 	maildir_index_sync,
 	mail_index_get_header,
 	mail_index_lookup,
 	mail_index_next,
         mail_index_lookup_uid_range,
-	mail_index_lookup_field,
-	mail_index_lookup_field_raw,
-	mail_index_cache_fields_later,
 	maildir_open_mail,
-	maildir_get_internal_date,
+	maildir_get_received_date,
 	mail_index_expunge,
 	maildir_index_update_flags,
-	mail_index_append_begin,
-	mail_index_append_end,
-	mail_index_append_abort,
-	mail_index_update_begin,
-	mail_index_update_end,
-	mail_index_update_abort,
-	mail_index_update_field,
-	mail_index_update_field_raw,
+	mail_index_append,
 	mail_index_get_last_error,
 	mail_index_get_last_error_text,
 

Index: maildir-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-index.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- maildir-index.h	15 Jun 2003 03:42:28 -0000	1.23
+++ maildir-index.h	6 Aug 2003 20:15:32 -0000	1.24
@@ -1,13 +1,11 @@
 #ifndef __MAILDIR_INDEX_H
 #define __MAILDIR_INDEX_H
 
+struct mail_cache_transaction_ctx;
+
 #include <sys/time.h>
-#include <dirent.h>
 #include "mail-index.h"
 
-/* ":2,DFRST" - leave the 2 extra for other clients' additions */
-#define MAILDIR_LOCATION_EXTRA_SPACE 10
-
 /* How often to try to flush dirty flags. */
 #define MAILDIR_DIRTY_FLUSH_TIMEOUT (60*5)
 
@@ -21,20 +19,22 @@
 		       const char **path);
 
 const char *maildir_get_location(struct mail_index *index,
-				 struct mail_index_record *rec);
+				 struct mail_index_record *rec, int *new_dir);
 enum mail_flags maildir_filename_get_flags(const char *fname,
 					   enum mail_flags default_flags);
 const char *maildir_filename_set_flags(const char *fname,
 				       enum mail_flags flags);
+void maildir_index_update_filename(struct mail_index *index, unsigned int uid,
+				   const char *fname, int new_dir);
 
-int maildir_index_rebuild(struct mail_index *index);
 int maildir_index_sync_readonly(struct mail_index *index,
 				const char *fname, int *found);
 int maildir_index_sync(struct mail_index *index, int minimal_sync,
 		       enum mail_lock_type lock_type, int *changes);
 
-int maildir_index_append_file(struct mail_index *index, const char *dir,
-			      const char *fname, int new_dir);
+int maildir_index_append_file(struct mail_cache_transaction_ctx **trans_ctx,
+			      struct mail_index *index, const char *fname,
+			      int new_dir);
 int maildir_index_update_flags(struct mail_index *index,
 			       struct mail_index_record *rec, unsigned int seq,
 			       enum mail_flags flags, int external_change);
@@ -42,7 +42,7 @@
 
 struct istream *maildir_open_mail(struct mail_index *index,
 				  struct mail_index_record *rec,
-				  time_t *internal_date, int *deleted);
+				  time_t *received_date, int *deleted);
 
 int maildir_expunge_mail(struct mail_index *index,
 			 struct mail_index_record *rec);

Index: maildir-open.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-open.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- maildir-open.c	18 May 2003 12:26:06 -0000	1.16
+++ maildir-open.c	6 Aug 2003 20:15:32 -0000	1.17
@@ -3,8 +3,8 @@
 #include "lib.h"
 #include "istream.h"
 #include "maildir-index.h"
-#include "mail-index-data.h"
 #include "mail-index-util.h"
+#include "mail-cache.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -15,13 +15,13 @@
 				  const char **fname, int *deleted)
 {
 	const char *path;
-	int fd = -1;
+	int new_dir, fd = -1;
 
-	*fname = maildir_get_location(index, rec);
+	*fname = maildir_get_location(index, rec, &new_dir);
 	if (*fname == NULL)
 		return -1;
 
-	if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+	if (new_dir) {
 		/* probably in new/ dir */
 		path = t_strconcat(index->mailbox_path, "/new/", *fname, NULL);
 		fd = open(path, O_RDONLY);
@@ -50,7 +50,7 @@
 
 struct istream *maildir_open_mail(struct mail_index *index,
 				  struct mail_index_record *rec,
-				  time_t *internal_date, int *deleted)
+				  time_t *received_date, int *deleted)
 {
 	struct stat st;
 	const char *fname;
@@ -84,13 +84,9 @@
 			return NULL;
 	}
 
-	if (internal_date != NULL) {
-		*internal_date = mail_get_internal_date(index, rec);
-
-		if (*internal_date == (time_t)-1) {
-			if (fstat(fd, &st) == 0)
-				*internal_date = st.st_mtime;
-		}
+	if (received_date != NULL) {
+		if (fstat(fd, &st) == 0)
+			*received_date = st.st_mtime;
 	}
 
 	if (index->mail_read_mmaped) {

Index: maildir-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-sync.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- maildir-sync.c	21 Jul 2003 14:35:39 -0000	1.58
+++ maildir-sync.c	6 Aug 2003 20:15:32 -0000	1.59
@@ -186,8 +186,8 @@
 #include "str.h"
 #include "maildir-index.h"
 #include "maildir-uidlist.h"
-#include "mail-index-data.h"
 #include "mail-index-util.h"
+#include "mail-cache.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -202,7 +202,6 @@
 enum maildir_file_action {
 	MAILDIR_FILE_ACTION_EXPUNGE,
         MAILDIR_FILE_ACTION_UPDATE_FLAGS,
-	MAILDIR_FILE_ACTION_UPDATE_CONTENT,
 	MAILDIR_FILE_ACTION_NEW,
 	MAILDIR_FILE_ACTION_NONE,
 
@@ -236,6 +235,7 @@
 	struct dirent *new_dent;
 
 	struct maildir_uidlist *uidlist;
+        struct mail_cache_transaction_ctx *trans_ctx;
 	unsigned int readonly_check:1;
 	unsigned int flag_updates:1;
 	unsigned int uidlist_rewrite:1;
@@ -276,41 +276,6 @@
 	return *s1 - *s2;
 }
 
-static void maildir_update_filename_memory(struct mail_index *index,
-					   const char *fname)
-{
-	char *new_fname;
-
-	if (index->new_filename_pool == NULL) {
-		index->new_filename_pool =
-			pool_alloconly_create("Maildir fname", 10240);
-	}
-	if (index->new_filenames == NULL) {
-		index->new_filenames =
-			hash_create(system_pool, index->new_filename_pool, 0,
-				    maildir_hash, maildir_cmp);
-	}
-
-	new_fname = p_strdup(index->new_filename_pool, fname);
-	hash_insert(index->new_filenames, new_fname, new_fname);
-}
-
-static int maildir_update_filename(struct maildir_sync_context *ctx,
-				   struct mail_index_record *rec,
-				   const char *new_fname)
-{
-	struct mail_index_update *update;
-
-	if (ctx->index->lock_type != MAIL_LOCK_EXCLUSIVE) {
-		maildir_update_filename_memory(ctx->index, new_fname);
-		return TRUE;
-	}
-
-	update = ctx->index->update_begin(ctx->index, rec);
-	ctx->index->update_field(update, DATA_FIELD_LOCATION, new_fname, 0);
-	return ctx->index->update_end(update);
-}
-
 static int maildir_update_flags(struct maildir_sync_context *ctx,
 				struct mail_index_record *rec,
 				unsigned int seq, const char *new_fname)
@@ -373,11 +338,6 @@
 			return FALSE;
 		}
 
-		if (!index->rebuilding) {
-			index->set_flags |= MAIL_INDEX_FLAG_REBUILD;
-			return FALSE;
-		}
-
 		index->header->uid_validity = ctx->uidlist->uid_validity;
 		i_assert(index->header->next_uid == 1);
 	}
@@ -393,47 +353,6 @@
 	return TRUE;
 }
 
-static int is_file_content_changed(struct mail_index *index,
-				   struct mail_index_record *rec,
-				   const char *dir, const char *fname)
-{
-#define DATA_HDR_SIZE (DATA_HDR_HEADER_SIZE | DATA_HDR_BODY_SIZE)
-	struct mail_index_data_record_header *data_hdr;
-	struct stat st;
-	const char *path;
-
-	if ((rec->data_fields & DATA_HDR_INTERNAL_DATE) == 0 &&
-	    (rec->data_fields & DATA_HDR_SIZE) != DATA_HDR_SIZE) {
-		/* nothing in cache, we can't know if it's changed */
-		return FALSE;
-	}
-
-	t_push();
-	path = t_strdup_printf("%s/%s", dir, fname);
-
-	if (stat(path, &st) < 0) {
-		if (errno != ENOENT)
-			index_file_set_syscall_error(index, path, "stat()");
-		t_pop();
-		return FALSE;
-	}
-	t_pop();
-
-	data_hdr = mail_index_data_lookup_header(index->data, rec);
-	if (data_hdr == NULL)
-		return FALSE;
-
-	if ((rec->data_fields & DATA_HDR_INTERNAL_DATE) != 0 &&
-	    st.st_mtime != data_hdr->internal_date)
-		return TRUE;
-
-	if ((rec->data_fields & DATA_HDR_SIZE) == DATA_HDR_SIZE &&
-	    (uoff_t)st.st_size != data_hdr->body_size + data_hdr->header_size)
-		return TRUE;
-
-	return FALSE;
-}
-
 static void uidlist_hash_get_filenames(void *key, void *value, void *context)
 {
 	buffer_t *buf = context;
@@ -464,6 +383,53 @@
 	return t1 < t2 ? -1 : t1 > t2 ? 1 : 0;
 }
 
+static int maildir_full_sync_finish_new_mails(struct maildir_sync_context *ctx)
+{
+	const char *dir, **new_files;
+	buffer_t *buf;
+	unsigned int i;
+	int new_dir;
+
+	ctx->uidlist_rewrite = TRUE;
+
+	/* then there's the completely new mails. sort them by the filename
+	   so we should get them to same order as they were created. */
+	buf = buffer_create_static_hard(ctx->pool,
+					ctx->new_count * sizeof(const char *));
+	hash_foreach(ctx->files, uidlist_hash_get_filenames, buf);
+	i_assert(buffer_get_used_size(buf) ==
+		 ctx->new_count * sizeof(const char *));
+
+	new_files = buffer_get_modifyable_data(buf, NULL);
+	qsort(new_files, ctx->new_count, sizeof(const char *),
+	      maildir_time_cmp);
+
+	if (!ctx->index->maildir_keep_new) {
+		dir = ctx->cur_dir;
+		new_dir = FALSE;
+	} else {
+		/* this is actually slightly wrong, because we don't really
+		   know if some of the new messages are in cur/ already.
+		   we could know that by saving it into buffer, but that'd
+		   require extra memory. luckily it doesn't really matter if
+		   we say it's in new/, but it's actually in cur/. we have
+		   to deal with such case anyway since another client might
+		   have just moved it. */
+		dir = ctx->new_dir;
+		new_dir = TRUE;
+		ctx->index->maildir_have_new = TRUE;
+	}
+
+	for (i = 0; i < ctx->new_count; i++) {
+		if (!maildir_index_append_file(&ctx->trans_ctx, ctx->index,
+					       new_files[i], new_dir))
+			return FALSE;
+	}
+	ctx->new_count = 0;
+
+	return TRUE;
+}
+
 static int maildir_full_sync_finish(struct maildir_sync_context *ctx)
 {
 	struct mail_index *index = ctx->index;
@@ -472,11 +438,10 @@
 	struct maildir_hash_rec *hash_rec;
 	struct maildir_uidlist_rec uid_rec;
         enum maildir_file_action action;
-	const char *fname, **new_files, *dir;
+	const char *fname, *dir;
 	void *orig_key, *orig_value;
-	unsigned int seq, first_seq, last_seq, uid, last_uid, i, new_flag;
+	unsigned int seq, first_seq, last_seq, uid, last_uid, new_flag;
 	int new_dir, skip_next;
-	buffer_t *buf;
 
 	if (ctx->new_count > 0) {
 		/* new mails, either they're already in uidlist or we have
@@ -512,7 +477,7 @@
 				return FALSE;
 		}
 
-		fname = maildir_get_location(index, rec);
+		fname = maildir_get_location(index, rec, NULL);
 		if (fname == NULL)
 			return FALSE;
 
@@ -536,20 +501,16 @@
 		    (ACTION(hash_rec) == MAILDIR_FILE_ACTION_UPDATE_FLAGS ||
 		     ACTION(hash_rec) == MAILDIR_FILE_ACTION_NONE)) {
 			/* it's UID has changed. shouldn't happen. */
-			i_warning("UID changed for %s/%s: %u -> %u",
-				  index->mailbox_path, fname, uid, uid_rec.uid);
-			hash_rec->action = MAILDIR_FILE_ACTION_UPDATE_CONTENT |
-				(hash_rec->action & MAILDIR_FILE_FLAGS);
+			index_set_corrupted(index,
+					    "UID changed for %s/%s: %u -> %u",
+					    index->mailbox_path, fname,
+					    uid, uid_rec.uid);
+			return FALSE;
 		}
 
 		action = hash_rec != NULL ?
 			ACTION(hash_rec) : MAILDIR_FILE_ACTION_NONE;
 		switch (action) {
-		case MAILDIR_FILE_ACTION_UPDATE_CONTENT:
-			hash_rec->action = MAILDIR_FILE_ACTION_NEW |
-				(hash_rec->action & MAILDIR_FILE_FLAGS);
-			ctx->new_count++;
-			/* fall through */
 		case MAILDIR_FILE_ACTION_EXPUNGE:
 			if (first_rec == NULL) {
 				first_rec = rec;
@@ -559,8 +520,10 @@
 			last_seq = seq;
 			break;
 		case MAILDIR_FILE_ACTION_UPDATE_FLAGS:
-			if (!maildir_update_filename(ctx, rec, orig_key))
-				return FALSE;
+			new_dir = (hash_rec->action &
+				   MAILDIR_FILE_FLAG_NEWDIR) != 0;
+			maildir_index_update_filename(index, rec->uid,
+						      orig_key, new_dir);
 			if (!maildir_update_flags(ctx, rec, seq, fname))
 				return FALSE;
 			/* fall through */
@@ -651,8 +614,8 @@
 				ctx->index->maildir_have_new = TRUE;
 			dir = new_flag != 0 ? ctx->new_dir : ctx->cur_dir;
 
-			if (!maildir_index_append_file(index, dir, orig_key,
-						       new_flag != 0))
+			if (!maildir_index_append_file(&ctx->trans_ctx, index,
+						       orig_key, new_flag != 0))
 				return FALSE;
 		}
 
@@ -677,48 +640,13 @@
 		index->last_uidlist_mtime = st.st_mtime;
 	}
 
-	if (ctx->new_count == 0 || !INDEX_IS_UIDLIST_LOCKED(index)) {
-		/* all done (or can't do it since we don't have lock) */
-		return TRUE;
-	}
-
-	ctx->uidlist_rewrite = TRUE;
-
-	/* then there's the completely new mails. sort them by the filename
-	   so we should get them to same order as they were created. */
-	buf = buffer_create_static_hard(ctx->pool,
-					ctx->new_count * sizeof(const char *));
-	hash_foreach(ctx->files, uidlist_hash_get_filenames, buf);
-	i_assert(buffer_get_used_size(buf) ==
-		 ctx->new_count * sizeof(const char *));
-
-	new_files = buffer_get_modifyable_data(buf, NULL);
-	qsort(new_files, ctx->new_count, sizeof(const char *),
-	      maildir_time_cmp);
-
-	if (!index->maildir_keep_new) {
-		dir = ctx->cur_dir;
-		new_dir = FALSE;
-	} else {
-		/* this is actually slightly wrong, because we don't really
-		   know if some of the new messages are in cur/ already.
-		   we could know that by saving it into buffer, but that'd
-		   require extra memory. luckily it doesn't really matter if
-		   we say it's in new/, but it's actually in cur/. we have
-		   to deal with such case anyway since another client might
-		   have just moved it. */
-		dir = ctx->new_dir;
-		new_dir = TRUE;
-		ctx->index->maildir_have_new = TRUE;
-	}
-
-	for (i = 0; i < ctx->new_count; i++) {
-		if (!maildir_index_append_file(index, dir,
-					       new_files[i], new_dir))
-			return FALSE;
-	}
+	if (ctx->new_count > 0 && INDEX_IS_UIDLIST_LOCKED(index))
+                maildir_full_sync_finish_new_mails(ctx);
 
-	ctx->new_count = 0;
+	/* all done (or can't do it since we don't have lock) */
+	ctx->index->maildir_synced_once = TRUE;
+	if (ctx->trans_ctx != NULL)
+		mail_cache_transaction_commit(ctx->trans_ctx);
 	return TRUE;
 }
 
@@ -730,12 +658,12 @@
 	struct maildir_hash_rec *hash_rec;
 	const char *fname;
 	size_t size;
-	int have_new;
+	int new_dir, have_new;
 
-	/* FIXME: kludge. we want to have pointers to data file, so we must
-	   make sure that it's base address doesn't change. this call makes
-	   sure it's fully mmaped in memory even when we begin */
-	if (mail_index_data_get_mmaped(index->data, &size) == NULL)
+	/* kludge. we want to have pointers to data file, so we must make sure
+	   that it's base address doesn't change. this call makes sure it's
+	   fully mmaped in memory even when we begin */
+	if (mail_cache_get_mmaped(index->cache, &size) == NULL)
 		return FALSE;
 
 	if (index->header->messages_count >= INT_MAX/32) {
@@ -744,6 +672,19 @@
 		return FALSE;
 	}
 
+	/* we're resyncing everything, so reset the filename hash */
+	if (index->new_filenames != NULL) {
+		hash_destroy(index->new_filenames);
+		index->new_filenames = NULL;
+	}
+
+	if (index->new_filename_pool != NULL)
+		p_clear(index->new_filename_pool);
+
+	/* reset synced-flag too, just in case something fails and we don't
+	   have up-to-date new_filenames */
+	ctx->index->maildir_synced_once = FALSE;
+
 	/* read current messages in index into hash */
 	size = nearest_power(index->header->messages_count *
 			     sizeof(struct maildir_hash_rec) + 1024);
@@ -757,15 +698,14 @@
 
 	rec = index->lookup(index, 1);
 	while (rec != NULL) {
-		fname = maildir_get_location(index, rec);
+		fname = maildir_get_location(index, rec, &new_dir);
 		if (fname == NULL)
 			return FALSE;
 
-		if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0)
+		if (new_dir)
 			have_new = TRUE;
 
-		if (!only_new ||
-		    (rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+		if (!only_new || new_dir) {
 			hash_rec = p_new(ctx->pool, struct maildir_hash_rec, 1);
 			hash_rec->rec = rec;
 			hash_rec->action = MAILDIR_FILE_ACTION_EXPUNGE;
@@ -841,20 +781,14 @@
 }
 
 static int maildir_full_sync_dir(struct maildir_sync_context *ctx,
-				 const char *dir, int new_dir,
-				 DIR *dirp, struct dirent *d)
+				 int new_dir, DIR *dirp, struct dirent *d)
 {
 	struct maildir_hash_rec *hash_rec;
 	void *orig_key, *orig_value;
-	int check_content_changes, newflag;
+	int newflag;
 
 	newflag = new_dir ? MAILDIR_FILE_FLAG_NEWDIR : 0;
 
-	/* Do we want to check changes in file contents? This slows down
-	   things as we need to do extra stat() for all files. */
-	check_content_changes = !ctx->readonly_check &&
-		getenv("MAILDIR_CHECK_CONTENT_CHANGES") != NULL;
-
 	do {
 		if (d->d_name[0] == '.')
 			continue;
@@ -889,25 +823,7 @@
 			continue;
 		}
 
-		if (!new_dir && (hash_rec->rec->index_flags &
-				 INDEX_MAIL_FLAG_MAILDIR_NEW) != 0 &&
-		    ctx->index->lock_type == MAIL_LOCK_EXCLUSIVE) {
-			/* mail was indexed in new/ but it has been
-			   moved to cur/ later */
-			hash_rec->rec->index_flags &=
-				~INDEX_MAIL_FLAG_MAILDIR_NEW;
-		}
-
-		if (check_content_changes &&
-		    is_file_content_changed(ctx->index, hash_rec->rec,
-					    dir, d->d_name)) {
-			/* file content changed, treat it as new message */
-			hash_rec->action =
-				MAILDIR_FILE_ACTION_UPDATE_CONTENT | newflag;
-
-			hash_insert(ctx->files, p_strdup(ctx->pool, d->d_name),
-				    hash_rec);
-		} else if (strcmp(orig_key, d->d_name) != 0) {
+		if (strcmp(orig_key, d->d_name) != 0) {
 			hash_rec->action =
 				MAILDIR_FILE_ACTION_UPDATE_FLAGS | newflag;
 
@@ -969,8 +885,8 @@
 	}
 
 	if (ctx->new_dent != NULL) {
-		if (!maildir_full_sync_dir(ctx, ctx->new_dir, TRUE,
-					   ctx->new_dirp, ctx->new_dent))
+		if (!maildir_full_sync_dir(ctx, TRUE, ctx->new_dirp,
+					   ctx->new_dent))
 			return FALSE;
                 ctx->new_dent = NULL;
 	}
@@ -981,8 +897,7 @@
 						    "opendir()");
 	}
 
-	failed = !maildir_full_sync_dir(ctx, ctx->cur_dir, FALSE,
-					dirp, readdir(dirp));
+	failed = !maildir_full_sync_dir(ctx, FALSE, dirp, readdir(dirp));
 
 	if (closedir(dirp) < 0) {
 		return index_file_set_syscall_error(ctx->index, ctx->cur_dir,
@@ -1000,8 +915,7 @@
 	if (!maildir_full_sync_init(ctx, TRUE))
 		return FALSE;
 
-	if (!maildir_full_sync_dir(ctx, ctx->new_dir, TRUE,
-				   ctx->new_dirp, ctx->new_dent))
+	if (!maildir_full_sync_dir(ctx, TRUE, ctx->new_dirp, ctx->new_dent))
 		return FALSE;
 	ctx->new_dent = NULL;
 
@@ -1098,8 +1012,8 @@
 				ctx->index->maildir_have_new = TRUE;
 
 			t_push();
-			if (!maildir_index_append_file(ctx->index, final_dir,
-						       d->d_name,
+			if (!maildir_index_append_file(&ctx->trans_ctx,
+						       ctx->index, d->d_name,
 						       !move_to_cur)) {
 				t_pop();
 				return FALSE;
@@ -1244,13 +1158,16 @@
 	void *orig_key, *orig_value;
 	const char *fname;
 	unsigned int seq;
+	int new_dir;
 
-	if (index->lock_type != MAIL_LOCK_EXCLUSIVE || !ctx->flag_updates)
+	if (!ctx->flag_updates) {
+		ctx->index->maildir_synced_once = TRUE;
 		return TRUE;
+	}
 
 	rec = index->lookup(index, 1); seq = 1;
 	while (rec != NULL) {
-		fname = maildir_get_location(index, rec);
+		fname = maildir_get_location(index, rec, NULL);
 		if (fname == NULL)
 			return FALSE;
 
@@ -1261,15 +1178,21 @@
 
 		if (hash_rec != NULL &&
 		    ACTION(hash_rec) == MAILDIR_FILE_ACTION_UPDATE_FLAGS) {
-			if (!maildir_update_filename(ctx, rec, orig_key))
-				return FALSE;
-			if (!maildir_update_flags(ctx, rec, seq, fname))
-				return FALSE;
+			new_dir = (hash_rec->action &
+				   MAILDIR_FILE_FLAG_NEWDIR) != 0;
+			maildir_index_update_filename(index, rec->uid,
+						      orig_key, new_dir);
+
+			if (index->lock_type == MAIL_LOCK_EXCLUSIVE) {
+				if (!maildir_update_flags(ctx, rec, seq, fname))
+					return FALSE;
+			}
 		}
 
 		rec = index->next(index, rec); seq++;
 	}
 
+	ctx->index->maildir_synced_once = TRUE;
 	return TRUE;
 }
 
@@ -1281,13 +1204,19 @@
 
 	i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
 
-	if (stat(ctx->cur_dir, &st) < 0) {
-		index_file_set_syscall_error(index, ctx->cur_dir, "stat()");
-		return FALSE;
-	}
+	if (!index->maildir_synced_once) {
+		/* we haven't synced yet in this session. do it */
+		cur_changed = TRUE;
+	} else {
+		if (stat(ctx->cur_dir, &st) < 0) {
+			index_file_set_syscall_error(index, ctx->cur_dir,
+						     "stat()");
+			return FALSE;
+		}
 
-	cur_changed = st.st_mtime != index->file_sync_stamp ||
-		index->maildir_cur_dirty != 0;
+		cur_changed = st.st_mtime != index->file_sync_stamp ||
+			index->maildir_cur_dirty != 0;
+	}
 
 	if (!cur_changed) {
 		if (!index->maildir_have_new) {
@@ -1325,6 +1254,9 @@
 
 static void maildir_index_sync_deinit(struct maildir_sync_context *ctx)
 {
+	// FIXME: remove new flags from cache if needed
+	if (ctx->trans_ctx != NULL)
+                mail_cache_transaction_end(ctx->trans_ctx);
 	if (ctx->uidlist != NULL)
 		maildir_uidlist_close(ctx->uidlist);
 	if (ctx->files != NULL)
@@ -1347,14 +1279,6 @@
 {
         struct maildir_sync_context *ctx;
 
-	if (index->new_filenames != NULL) {
-		hash_destroy(index->new_filenames);
-		index->new_filenames = NULL;
-	}
-
-	if (index->new_filename_pool != NULL)
-		p_clear(index->new_filename_pool);
-
 	ctx = t_new(struct maildir_sync_context, 1);
 	ctx->index = index;
 	ctx->new_dir = t_strconcat(index->mailbox_path, "/new", NULL);
@@ -1374,7 +1298,7 @@
 
 	ret = maildir_index_sync_context_readonly(ctx);
 
-	if (!ret)
+	if (!ret || ctx->files == NULL)
 		*found = FALSE;
 	else {
 		hash_rec = hash_lookup(ctx->files, fname);

Index: maildir-uidlist.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-uidlist.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- maildir-uidlist.c	5 Jul 2003 20:33:18 -0000	1.8
+++ maildir-uidlist.c	6 Aug 2003 20:15:32 -0000	1.9
@@ -155,7 +155,7 @@
 
 	rec = index->lookup(index, 1);
 	while (rec != NULL) {
-		fname = maildir_get_location(index, rec);
+		fname = maildir_get_location(index, rec, NULL);
 		if (fname == NULL)
 			return FALSE;
 

Index: maildir-update-flags.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-update-flags.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- maildir-update-flags.c	15 Jun 2003 02:22:28 -0000	1.6
+++ maildir-update-flags.c	6 Aug 2003 20:15:32 -0000	1.7
@@ -1,17 +1,55 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "hash.h"
 #include "ioloop.h"
 #include "maildir-index.h"
 #include "mail-index-util.h"
+#include "mail-cache.h"
 
 #include <stdio.h>
 
+static int update_filename(struct mail_index *index,
+			   struct mail_index_record *rec)
+{
+	const char *old_fname, *old_path, *new_fname, *new_path;
+	enum mail_index_record_flag flags;
+
+	old_fname = maildir_get_location(index, rec, NULL);
+	if (old_fname == NULL)
+		return -1;
+
+	flags = mail_cache_get_index_flags(index->cache, rec);
+
+	old_path = t_strconcat(index->mailbox_path,
+			       (flags & MAIL_INDEX_FLAG_MAILDIR_NEW) != 0 ?
+			       "/new/" : "/cur/", old_fname, NULL);
+
+	new_fname = maildir_filename_set_flags(old_fname, rec->msg_flags);
+	new_path = t_strconcat(index->mailbox_path, "/cur/", new_fname, NULL);
+
+	if (strcmp(old_path, new_path) == 0 ||
+	    rename(old_path, new_path) == 0) {
+		flags &= ~(MAIL_INDEX_FLAG_DIRTY | MAIL_INDEX_FLAG_MAILDIR_NEW);
+		if (!mail_cache_update_index_flags(index->cache, rec, flags))
+			return -1;
+		return 1;
+	} else {
+		if (errno != ENOENT && errno != EACCES &&
+		    !ENOSPACE(errno)) {
+			index_set_error(index,
+					"rename(%s, %s) failed: %m",
+					old_path, new_path);
+			return -1;
+		}
+		return 0;
+	}
+}
+
 int maildir_try_flush_dirty_flags(struct mail_index *index, int force)
 {
 	struct mail_index_record *rec;
-	const char *old_fname, *old_path, *new_fname, *new_path;
-	int flag, dirty = FALSE;
+	int ret, dirty = FALSE;
 
 	if (index->next_dirty_flush == 0 ||
 	    (ioloop_time < index->next_dirty_flush && !force))
@@ -20,44 +58,30 @@
 	if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
+	ret = mail_cache_lock(index->cache, !force);
+	if (ret <= 0)
+		return ret == 0;
+        mail_cache_unlock_later(index->cache);
+
 	rec = index->lookup(index, 1);
 	while (rec != NULL) {
-		if ((rec->index_flags & INDEX_MAIL_FLAG_DIRTY) != 0) {
-			old_fname = maildir_get_location(index, rec);
-			if (old_fname == NULL)
-				return FALSE;
-
-			flag = (rec->index_flags &
-				INDEX_MAIL_FLAG_MAILDIR_NEW) != 0;
-			old_path = t_strconcat(index->mailbox_path,
-					       flag ? "/new/" : "/cur/",
-					       old_fname, NULL);
-
-			new_fname = maildir_filename_set_flags(old_fname,
-							       rec->msg_flags);
-			new_path = t_strconcat(index->mailbox_path,
-					       "/cur/", new_fname, NULL);
-
-			if (strcmp(old_path, new_path) == 0 ||
-			    rename(old_path, new_path) == 0)
-                                rec->index_flags &= ~INDEX_MAIL_FLAG_DIRTY;
-			else {
+		if ((mail_cache_get_index_flags(index->cache, rec) &
+		     MAIL_INDEX_FLAG_DIRTY) != 0) {
+			ret = update_filename(index, rec);
+			if (ret < 0)
+				break;
+			if (ret == 0)
 				dirty = TRUE;
-				if (errno != ENOENT && errno != EACCES &&
-				    !ENOSPACE(errno)) {
-					index_set_error(index,
-						"rename(%s, %s) failed: %m",
-						old_path, new_path);
-					return FALSE;
-				}
-			}
 		}
 
 		rec = index->next(index, rec);
 	}
 
+	if (ret < 0)
+		return FALSE;
+
 	if (!dirty) {
-		index->header->flags &= ~MAIL_INDEX_FLAG_DIRTY_MESSAGES;
+		index->header->flags &= ~MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES;
 		index->next_dirty_flush = 0;
 	} else {
 		index->next_dirty_flush =
@@ -88,13 +112,12 @@
 	return -1;
 }
 
-static int maildir_rename_mail_file(struct mail_index *index,
-				    struct mail_index_record *rec,
+static int maildir_rename_mail_file(struct mail_index *index, int new_dir,
 				    const char *old_fname, const char *new_path)
 {
 	const char *path;
 
-	if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+	if (new_dir) {
 		/* probably in new/ dir */
 		path = t_strconcat(index->mailbox_path, "/new/",
 				   old_fname, NULL);
@@ -117,14 +140,15 @@
 			       enum mail_flags flags, const char **new_fname_r)
 {
 	const char *old_fname, *new_fname, *new_path;
-	int i, ret, found;
+        enum mail_index_record_flag index_flags;
+	int i, ret, found, new_dir;
 
 	new_fname = new_path = NULL;
 
 	i = 0;
 	do {
 		/* we need to update the flags in the file name */
-		old_fname = maildir_get_location(index, rec);
+		old_fname = maildir_get_location(index, rec, &new_dir);
 		if (old_fname == NULL)
 			return FALSE;
 
@@ -139,21 +163,17 @@
 		if (strcmp(old_fname, new_fname) == 0)
 			ret = 1;
 		else {
-			ret = maildir_rename_mail_file(index, rec, old_fname,
-						       new_path);
+			ret = maildir_rename_mail_file(index, new_dir,
+						       old_fname, new_path);
 			if (ret == -1)
 				return FALSE;
 
 			if (ret == 1) {
-				if (index->maildir_keep_new &&
-				    (rec->index_flags &
-				     INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) {
+				if (index->maildir_keep_new && new_dir) {
 					/* looks like we have some more space
 					   again, see if we could move mails
 					   from new/ to cur/ again */
 					index->maildir_keep_new = FALSE;
-					rec->index_flags &=
-						~INDEX_MAIL_FLAG_MAILDIR_NEW;
 				}
 
 				/* cur/ was updated, set it dirty-synced */
@@ -173,15 +193,26 @@
 		i++;
 	} while (i < 10 && ret == 0);
 
-	if (ret != 1) {
-		/* we couldn't actually rename() the file now.
-		   leave it's flags dirty so they get changed later. */
-		rec->index_flags |= INDEX_MAIL_FLAG_DIRTY;
-		index->header->flags |= MAIL_INDEX_FLAG_DIRTY_MESSAGES;
-		index->next_dirty_flush =
-			ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT;
-		*new_fname_r = NULL;
+	if (ret == 1)
+		return TRUE;
+
+	/* we couldn't actually rename() the file now.
+	   leave it's flags dirty so they get changed later. */
+	index_flags = mail_cache_get_index_flags(index->cache, rec);
+	if ((index_flags & MAIL_INDEX_FLAG_DIRTY) == 0) {
+		if (mail_cache_lock(index->cache, FALSE) <= 0)
+			return FALSE;
+		mail_cache_unlock_later(index->cache);
+
+		index_flags |= MAIL_INDEX_FLAG_DIRTY;
+		mail_cache_update_index_flags(index->cache, rec, index_flags);
+
+		index->header->flags |= MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES;
 	}
+
+	index->next_dirty_flush =
+		ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT;
+	*new_fname_r = NULL;
 	return TRUE;
 }
 
@@ -189,7 +220,6 @@
 			       struct mail_index_record *rec, unsigned int seq,
 			       enum mail_flags flags, int external_change)
 {
-	struct mail_index_update *update;
 	const char *new_fname;
 	int failed = FALSE;
 
@@ -200,11 +230,8 @@
 	}
 
 	if (new_fname != NULL) {
-		/* update the filename in index */
-		update = index->update_begin(index, rec);
-		index->update_field(update, DATA_FIELD_LOCATION, new_fname, 0);
-		if (!index->update_end(update))
-			failed = TRUE;
+		maildir_index_update_filename(index, rec->uid,
+					      new_fname, FALSE);
 	}
 
 	if (!failed && !mail_index_update_flags(index, rec, seq, flags,

--- maildir-rebuild.c DELETED ---



More information about the dovecot-cvs mailing list