[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-save.c, 1.105, 1.106 mbox-sync-private.h, 1.63, 1.64 mbox-sync.c, 1.201, 1.202

tss at dovecot.org tss at dovecot.org
Wed Mar 7 17:38:27 EET 2007


Update of /var/lib/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv32259

Modified Files:
	mbox-save.c mbox-sync-private.h mbox-sync.c 
Log Message:
Keep track of the mbox dirty state better. Also when moving mails inside
an mbox without changing the file's size, make sure the file's
mtime changes even if it means sleeping for a second.



Index: mbox-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-save.c,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -d -r1.105 -r1.106
--- mbox-save.c	19 Feb 2007 14:45:51 -0000	1.105
+++ mbox-save.c	7 Mar 2007 15:38:24 -0000	1.106
@@ -300,13 +300,15 @@
 				return -1;
 		}
 
-		if (!want_mail) {
-			/* assign UIDs only if mbox doesn't require syncing */
-			ret = mbox_sync_has_changed(mbox, TRUE);
-			if (ret < 0)
-				return -1;
-			if (ret == 0)
-				mbox_save_init_sync(t);
+		/* update mbox_sync_dirty state */
+		ret = mbox_sync_has_changed(mbox, TRUE);
+		if (ret < 0)
+			return -1;
+		if (!want_mail && ret == 0) {
+			/* we're not required to assign UIDs for the appended
+			   mails immediately. do it only if it doesn't require
+			   syncing. */
+			mbox_save_init_sync(t);
 		}
 
 		if (mbox_seek_to_end(ctx, &ctx->append_offset) < 0)
@@ -648,7 +650,7 @@
 		if (fstat(ctx->mbox->mbox_fd, &st) < 0) {
 			mbox_set_syscall_error(ctx->mbox, "fstat()");
 			ret = -1;
-		} else {
+		} else if (!ctx->mbox->mbox_sync_dirty) {
 			uint32_t sync_stamp = st.st_mtime;
 			uint64_t sync_size = st.st_size;
 

Index: mbox-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- mbox-sync-private.h	28 Feb 2007 19:55:31 -0000	1.63
+++ mbox-sync-private.h	7 Mar 2007 15:38:24 -0000	1.64
@@ -101,6 +101,9 @@
 	struct istream *input, *file_input;
 	int write_fd;
 
+	time_t orig_mtime;
+	uoff_t orig_size;
+
 	struct mail_index_sync_ctx *index_sync_ctx;
 	struct mail_index_view *sync_view;
 	struct mail_index_transaction *t;
@@ -132,6 +135,7 @@
 	/* global flags: */
 	unsigned int delay_writes:1;
 	unsigned int renumber_uids:1;
+	unsigned int moved_offsets:1;
 };
 
 int mbox_sync(struct mbox_mailbox *mbox, enum mbox_sync_flags flags);

Index: mbox-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.201
retrieving revision 1.202
diff -u -d -r1.201 -r1.202
--- mbox-sync.c	7 Mar 2007 15:34:58 -0000	1.201
+++ mbox-sync.c	7 Mar 2007 15:38:24 -0000	1.202
@@ -51,10 +51,9 @@
 
 #include <stddef.h>
 #include <stdlib.h>
+#include <utime.h>
 #include <sys/stat.h>
 
-#define MBOX_SYNC_SECS 1
-
 /* The text below was taken exactly as c-client wrote it to my mailbox,
    so it's probably copyrighted by University of Washington. */
 #define PSEUDO_MESSAGE_BODY \
@@ -656,6 +655,7 @@
 		    (mails[i].flags & MBOX_EXPUNGED) != 0)
 			continue;
 
+		sync_ctx->moved_offsets = TRUE;
 		offset = mails[i].from_offset;
 		mail_index_update_ext(sync_ctx->t, mails[i].idx_seq,
 				      ext_idx, &offset, NULL);
@@ -1391,6 +1391,38 @@
 		return -1;
 	}
 
+	if (sync_ctx->moved_offsets &&
+	    ((uint64_t)st->st_size == sync_ctx->hdr->sync_size ||
+	     (uint64_t)st->st_size == sync_ctx->orig_size)) {
+		/* We moved messages inside the mbox file without changing
+		   the file's size. If mtime doesn't change, another process
+		   not using the same index file as us can't know that the file
+		   was changed. So make sure the mtime changes. This should
+		   happen rarely enough that the sleeping doesn't become a
+		   performance problem.
+
+		   Note that to do this perfectly safe we should do this wait
+		   whenever mails are moved or expunged, regardless of whether
+		   the file's size changed. That however could become a
+		   performance problem and the consequences of being wrong are
+		   quite minimal (an extra logged error message). */
+		while (sync_ctx->orig_mtime == st->st_mtime) {
+			usleep(500000);
+			if (utime(sync_ctx->mbox->path, NULL) < 0) {
+				mbox_set_syscall_error(sync_ctx->mbox,
+						       "utime()");
+				return -1;
+			}
+
+			st = i_stream_stat(sync_ctx->file_input, FALSE);
+			if (st == NULL) {
+				mbox_set_syscall_error(sync_ctx->mbox,
+						       "i_stream_stat()");
+				return -1;
+			}
+		}
+	}
+
 	/* only reason not to have UID validity at this point is if the file
 	   is entirely empty. In that case just make up a new one if needed. */
 	i_assert(sync_ctx->base_uid_validity != 0 || st->st_size == 0);
@@ -1480,6 +1512,8 @@
 		mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()");
 		return -1;
 	}
+	sync_ctx->orig_size = st->st_size;
+	sync_ctx->orig_mtime = st->st_mtime;
 
 	if ((flags & MBOX_SYNC_FORCE_SYNC) != 0) {
 		/* forcing a full sync. assume file has changed. */
@@ -1570,8 +1604,10 @@
 		return 0;
 	}
 
-	if (!mbox->mbox_sync_dirty || !leave_dirty)
+	if (!mbox->mbox_sync_dirty || !leave_dirty) {
+		mbox->mbox_sync_dirty = TRUE;
 		return 1;
+	}
 
 	return st->st_mtime != mbox->mbox_dirty_stamp ||
 		st->st_size != mbox->mbox_dirty_size;



More information about the dovecot-cvs mailing list