changeset 1552:bc3307f2f35d HEAD

Only NOOP and CHECK will now always do a real mailbox sync. Other commands will also do it but no often than once in 5 seconds. Also with maildir we don't anymore try to sync it before running commands since syncing is now done automatically whenever we try to access a file that doesn't exist.
author Timo Sirainen <tss@iki.fi>
date Sun, 15 Jun 2003 06:42:28 +0300
parents 313779bde3ec
children 25cef50e3b0e
files src/imap/cmd-append.c src/imap/cmd-capability.c src/imap/cmd-copy.c src/imap/cmd-fetch.c src/imap/cmd-search.c src/imap/cmd-sort.c src/imap/cmd-store.c src/imap/cmd-thread.c src/imap/commands-util.c src/imap/commands-util.h src/lib-index/mail-index-open.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-index.h src/lib-index/maildir/maildir-rebuild.c src/lib-index/maildir/maildir-sync.c src/lib-index/mbox/mbox-index.h src/lib-index/mbox/mbox-rewrite.c src/lib-index/mbox/mbox-sync.c src/lib-storage/index/index-copy.c src/lib-storage/index/index-expunge.c src/lib-storage/index/index-fetch.c src/lib-storage/index/index-search.c src/lib-storage/index/index-status.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/index-update-flags.c src/lib-storage/index/maildir/maildir-copy.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/mail-storage.h
diffstat 29 files changed, 90 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/cmd-append.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-append.c	Sun Jun 15 06:42:28 2003 +0300
@@ -207,7 +207,7 @@
 	box->close(box);
 
 	if (!failed) {
-		client_sync_full(client);
+		client_sync_full_fast(client);
 		client_send_tagline(client, "OK Append completed.");
 	}
 	return TRUE;
--- a/src/imap/cmd-capability.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-capability.c	Sun Jun 15 06:42:28 2003 +0300
@@ -7,7 +7,7 @@
 {
 	client_send_line(client, "* CAPABILITY " CAPABILITY_STRING);
 
-	client_sync_full(client);
+	client_sync_full_fast(client);
 	client_send_tagline(client, "OK Capability completed.");
 	return TRUE;
 }
--- a/src/imap/cmd-copy.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-copy.c	Sun Jun 15 06:42:28 2003 +0300
@@ -31,14 +31,14 @@
 	ret = client->mailbox->copy(client->mailbox, destbox,
 				    messageset, client->cmd_uid);
 
-	/* sync always - if COPY fails because of expunges they'll get
-	   synced here */
-	client_sync_full(client);
-
-	if (ret)
+	if (ret) {
+		client_sync_full_fast(client);
 		client_send_tagline(client, "OK Copy completed.");
-	else
+	} else {
+		/* if COPY fails because of expunges they'll get synced here */
+		client_sync_full(client);
 		client_send_storage_error(client);
+	}
 
 	destbox->close(destbox);
 	return TRUE;
--- a/src/imap/cmd-fetch.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-fetch.c	Sun Jun 15 06:42:28 2003 +0300
@@ -354,7 +354,7 @@
 		if ((client_workarounds &
 		     WORKAROUND_OE6_FETCH_NO_NEWMAIL) == 0) {
 			if (client->cmd_uid)
-				client_sync_full(client);
+				client_sync_full_fast(client);
 			else
 				client_sync_without_expunges(client);
 		}
--- a/src/imap/cmd-search.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-search.c	Sun Jun 15 06:42:28 2003 +0300
@@ -92,7 +92,7 @@
 		client_send_tagline(client, t_strconcat("NO ", error, NULL));
 	} else if (imap_search(client, charset, sargs)) {
 		if (client->cmd_uid)
-			client_sync_full(client);
+			client_sync_full_fast(client);
 		else
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Search completed.");
--- a/src/imap/cmd-sort.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-sort.c	Sun Jun 15 06:42:28 2003 +0300
@@ -123,7 +123,7 @@
 	} else if (imap_sort(client, charset, sargs, sorting)) {
 		/* NOTE: syncing is allowed when returning UIDs */
 		if (client->cmd_uid)
-			client_sync_full(client);
+			client_sync_full_fast(client);
 		else
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Sort completed.");
--- a/src/imap/cmd-store.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-store.c	Sun Jun 15 06:42:28 2003 +0300
@@ -75,7 +75,7 @@
 					  client->cmd_uid, &flags,
 					  modify_type, !silent, &all_found)) {
 		if (client->cmd_uid)
-			client_sync_full(client);
+			client_sync_full_fast(client);
 		else
 			client_sync_without_expunges(client);
 		client_send_tagline(client, all_found ? "OK Store completed." :
--- a/src/imap/cmd-thread.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/cmd-thread.c	Sun Jun 15 06:42:28 2003 +0300
@@ -65,7 +65,7 @@
 	} else if (imap_thread(client, charset, sargs, threading)) {
 		/* NOTE: syncing is allowed when returning UIDs */
 		if (client->cmd_uid)
-			client_sync_full(client);
+			client_sync_full_fast(client);
 		else
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Search completed.");
--- a/src/imap/commands-util.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/commands-util.c	Sun Jun 15 06:42:28 2003 +0300
@@ -94,7 +94,16 @@
 void client_sync_full(struct client *client)
 {
 	if (client->mailbox != NULL) {
-		if (!client->mailbox->sync(client->mailbox, TRUE))
+		if (!client->mailbox->sync(client->mailbox, 0))
+                        client_send_untagged_storage_error(client);
+	}
+}
+
+void client_sync_full_fast(struct client *client)
+{
+	if (client->mailbox != NULL) {
+		if (!client->mailbox->sync(client->mailbox,
+					   MAIL_SYNC_FLAG_FAST))
                         client_send_untagged_storage_error(client);
 	}
 }
@@ -102,7 +111,9 @@
 void client_sync_without_expunges(struct client *client)
 {
 	if (client->mailbox != NULL) {
-		if (!client->mailbox->sync(client->mailbox, FALSE))
+		if (!client->mailbox->sync(client->mailbox,
+                                           MAIL_SYNC_FLAG_NO_EXPUNGES |
+					   MAIL_SYNC_FLAG_FAST))
 			client_send_untagged_storage_error(client);
 	}
 }
--- a/src/imap/commands-util.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/imap/commands-util.h	Sun Jun 15 06:42:28 2003 +0300
@@ -20,6 +20,9 @@
    FETCH FLAGS, EXISTS and RECENT responses. */
 void client_sync_full(struct client *client);
 
+/* Synchronize fast. */
+void client_sync_full_fast(struct client *client);
+
 /* Synchronize all but expunges with client. */
 void client_sync_without_expunges(struct client *client);
 
--- a/src/lib-index/mail-index-open.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/mail-index-open.c	Sun Jun 15 06:42:28 2003 +0300
@@ -136,7 +136,8 @@
 	if (!rebuilt) {
 		/* sync ourself. do it before updating cache and compression
 		   which may happen because of this. */
-		if (!index->sync_and_lock(index, MAIL_LOCK_SHARED, NULL) &&
+		if (!index->sync_and_lock(index, FALSE,
+					  MAIL_LOCK_SHARED, NULL) &&
 		    !index->nodiskspace)
 			return FALSE;
 
--- a/src/lib-index/mail-index.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/mail-index.h	Sun Jun 15 06:42:28 2003 +0300
@@ -247,8 +247,10 @@
 	   lock when calling this function. The data_lock_type specifies what
 	   lock should be set to data file (mbox file). This function may
 	   leave the index in ANY locking state. If changes is non-NULL, it's
-	   set to TRUE if any changes were noticed. */
-	int (*sync_and_lock)(struct mail_index *index,
+	   set to TRUE if any changes were noticed. If minimal_sync is TRUE,
+	   we do as little as possible to get data file locked (ie. noop with
+	   maildir). */
+	int (*sync_and_lock)(struct mail_index *index, int minimal_sync,
 			     enum mail_lock_type data_lock_type, int *changes);
 
 	/* Returns the index header (never fails). The index needs to be
--- a/src/lib-index/maildir/maildir-index.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/maildir/maildir-index.h	Sun Jun 15 06:42:28 2003 +0300
@@ -30,7 +30,7 @@
 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 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,
--- a/src/lib-index/maildir/maildir-rebuild.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/maildir/maildir-rebuild.c	Sun Jun 15 06:42:28 2003 +0300
@@ -44,7 +44,7 @@
 	}
 
 	/* read the mails by syncing */
-	if (!index->sync_and_lock(index, MAIL_LOCK_UNLOCK, NULL))
+	if (!index->sync_and_lock(index, FALSE, MAIL_LOCK_UNLOCK, NULL))
 		return FALSE;
 
 	/* rebuild is complete - remove the flag */
--- a/src/lib-index/maildir/maildir-sync.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/maildir/maildir-sync.c	Sun Jun 15 06:42:28 2003 +0300
@@ -1337,7 +1337,7 @@
 	return ret;
 }
 
-int maildir_index_sync(struct mail_index *index,
+int maildir_index_sync(struct mail_index *index, int minimal_sync,
 		       enum mail_lock_type data_lock_type __attr_unused__,
 		       int *changes)
 {
@@ -1349,6 +1349,9 @@
 	if (changes != NULL)
 		*changes = FALSE;
 
+	if (minimal_sync)
+		return TRUE;
+
 	ctx = maildir_sync_context_new(index);
 	ret = maildir_index_sync_context(ctx, changes);
         maildir_index_sync_deinit(ctx);
--- a/src/lib-index/mbox/mbox-index.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/mbox/mbox-index.h	Sun Jun 15 06:42:28 2003 +0300
@@ -56,7 +56,7 @@
 mbox_index_alloc(const char *mbox_path, const char *index_dir,
 		 const char *control_dir);
 int mbox_index_rebuild(struct mail_index *index);
-int mbox_index_sync(struct mail_index *index,
+int mbox_index_sync(struct mail_index *index, int minimal_sync,
 		    enum mail_lock_type lock_type, int *changes);
 int mbox_sync_full(struct mail_index *index);
 struct istream *mbox_open_mail(struct mail_index *index,
--- a/src/lib-index/mbox/mbox-rewrite.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/mbox/mbox-rewrite.c	Sun Jun 15 06:42:28 2003 +0300
@@ -600,8 +600,8 @@
 			if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
 				break;
 
-			if (!index->sync_and_lock(index, MAIL_LOCK_EXCLUSIVE,
-						  NULL))
+			if (!index->sync_and_lock(index, FALSE,
+						  MAIL_LOCK_EXCLUSIVE, NULL))
 				break;
 		}
 
--- a/src/lib-index/mbox/mbox-sync.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-index/mbox/mbox-sync.c	Sun Jun 15 06:42:28 2003 +0300
@@ -65,7 +65,7 @@
 	return mbox_sync_full(index);
 }
 
-int mbox_index_sync(struct mail_index *index,
+int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__,
 		    enum mail_lock_type data_lock_type, int *changes)
 {
 	struct stat st;
--- a/src/lib-storage/index/index-copy.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-copy.c	Sun Jun 15 06:42:28 2003 +0300
@@ -64,7 +64,8 @@
 		if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
 			return FALSE;
 	} else {
-		if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_SHARED))
+		if (!index_storage_sync_and_lock(ibox, TRUE, TRUE,
+						 MAIL_LOCK_SHARED))
 			return FALSE;
 	}
 
--- a/src/lib-storage/index/index-expunge.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-expunge.c	Sun Jun 15 06:42:28 2003 +0300
@@ -78,7 +78,8 @@
 	if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
-	if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_EXCLUSIVE))
+	if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+					 MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
 	/* modifylog must be marked synced before expunging
--- a/src/lib-storage/index/index-fetch.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-fetch.c	Sun Jun 15 06:42:28 2003 +0300
@@ -42,7 +42,8 @@
 
 	check_mail = (client_workarounds &
 		      WORKAROUND_OE6_FETCH_NO_NEWMAIL) == 0;
-	if (!index_storage_sync_and_lock(ibox, check_mail, MAIL_LOCK_SHARED))
+	if (!index_storage_sync_and_lock(ibox, check_mail, TRUE,
+					 MAIL_LOCK_SHARED))
 		return NULL;
 
 	if (update_seen != NULL && *update_seen &&
--- a/src/lib-storage/index/index-search.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-search.c	Sun Jun 15 06:42:28 2003 +0300
@@ -926,7 +926,7 @@
 		return NULL;
 	}
 
-	if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_SHARED))
+	if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_SHARED))
 		return NULL;
 
 	ctx = i_new(struct mail_search_context, 1);
--- a/src/lib-storage/index/index-status.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-status.c	Sun Jun 15 06:42:28 2003 +0300
@@ -89,7 +89,8 @@
 	if ((items & STATUS_MESSAGE_COUNTS) != 0) {
 		/* if we're doing STATUS for selected mailbox, we have to sync
 		   it first or STATUS reply may give different data */
-		if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_UNLOCK))
+		if (!index_storage_sync_and_lock(ibox, TRUE, FALSE,
+						 MAIL_LOCK_UNLOCK))
 			return FALSE;
 
 		if (!index_storage_sync_modifylog(ibox, FALSE)) {
--- a/src/lib-storage/index/index-storage.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-storage.h	Sun Jun 15 06:42:28 2003 +0300
@@ -52,7 +52,8 @@
 		   int readonly, int fast);
 int index_storage_close(struct mailbox *box);
 
-int index_storage_sync_and_lock(struct index_mailbox *ibox, int sync_size,
+int index_storage_sync_and_lock(struct index_mailbox *ibox,
+				int sync_size, int minimal_sync,
 				enum mail_lock_type data_lock_type);
 int index_storage_sync_modifylog(struct index_mailbox *ibox, int hide_deleted);
 
@@ -82,7 +83,7 @@
 int index_storage_get_status(struct mailbox *box,
 			     enum mailbox_status_items items,
 			     struct mailbox_status *status);
-int index_storage_sync(struct mailbox *box, int sync_expunges);
+int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags);
 int index_storage_update_flags(struct mailbox *box, const char *messageset,
 			       int uidset, const struct mail_full_flags *flags,
 			       enum modify_type modify_type, int notify,
--- a/src/lib-storage/index/index-sync.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-sync.c	Sun Jun 15 06:42:28 2003 +0300
@@ -7,6 +7,9 @@
 #include "mail-modifylog.h"
 #include "mail-custom-flags.h"
 
+/* How often to do full sync when fast sync flag is set. */
+#define MAILBOX_FULL_SYNC_INTERVAL 5
+
 static void index_storage_sync_size(struct index_mailbox *ibox)
 {
 	struct mail_storage *storage = ibox->box.storage;
@@ -29,7 +32,8 @@
 	}
 }
 
-int index_storage_sync_and_lock(struct index_mailbox *ibox, int sync_size,
+int index_storage_sync_and_lock(struct index_mailbox *ibox,
+				int sync_size, int minimal_sync,
 				enum mail_lock_type data_lock_type)
 {
 	struct mail_storage *storage = ibox->box.storage;
@@ -39,7 +43,8 @@
         set_shared_lock = ibox->index->lock_type != MAIL_LOCK_EXCLUSIVE;
 
         index_storage_init_lock_notify(ibox);
-	failed = !index->sync_and_lock(index, data_lock_type, &changes);
+	failed = !index->sync_and_lock(index, minimal_sync,
+				       data_lock_type, &changes);
 	ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
 
 	if (!failed) {
@@ -209,19 +214,29 @@
 	return TRUE;
 }
 
-int index_storage_sync(struct mailbox *box, int sync_expunges)
+int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags)
 {
 	struct index_mailbox *ibox = (struct index_mailbox *) box;
 	int ret;
 
-	ibox->sync_last_check = ioloop_time;
+	if ((flags & MAIL_SYNC_FLAG_FAST) == 0 ||
+	    ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
+		ibox->sync_last_check = ioloop_time;
 
-	if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_UNLOCK))
-		return FALSE;
+		if (!index_storage_sync_and_lock(ibox, FALSE, FALSE,
+						 MAIL_LOCK_UNLOCK))
+			return FALSE;
+	} else {
+		/* check only modify log */
+		if (!index_storage_lock(ibox, MAIL_LOCK_SHARED)) {
+			(void)index_storage_lock(ibox, MAIL_LOCK_UNLOCK);
+			return FALSE;
+		}
+	}
 
 	/* FIXME: we could sync flags always, but expunges in the middle
 	   could make it a bit more difficult and slower */
-	if (sync_expunges ||
+	if ((flags & MAIL_SYNC_FLAG_NO_EXPUNGES) == 0 ||
 	    mail_modifylog_get_expunge_count(ibox->index->modifylog) == 0)
 		ret = index_storage_sync_modifylog(ibox, FALSE);
 	else
--- a/src/lib-storage/index/index-update-flags.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/index-update-flags.c	Sun Jun 15 06:42:28 2003 +0300
@@ -83,7 +83,7 @@
 	if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
-	if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_UNLOCK))
+	if (!index_storage_sync_and_lock(ibox, TRUE, TRUE, MAIL_LOCK_UNLOCK))
 		return FALSE;
 
 	mail_flags &= ~MAIL_RECENT; /* \Recent can't be changed */
--- a/src/lib-storage/index/maildir/maildir-copy.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Sun Jun 15 06:42:28 2003 +0300
@@ -151,7 +151,7 @@
         struct messageset_context *ctx;
 	int exdev, ret, ret2;
 
-	if (!index_storage_sync_and_lock(src, TRUE, MAIL_LOCK_SHARED))
+	if (!src->index->set_lock(src->index, MAIL_LOCK_SHARED))
 		return -1;
 
 	ctx = index_messageset_init(src, messageset, uidset, FALSE);
--- a/src/lib-storage/index/mbox/mbox-save.c	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Sun Jun 15 06:42:28 2003 +0300
@@ -325,7 +325,8 @@
 		return NULL;
 	}
 
-	if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_EXCLUSIVE))
+	if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+					 MAIL_LOCK_EXCLUSIVE))
 		return NULL;
 
 	ctx = i_new(struct mail_save_context, 1);
--- a/src/lib-storage/mail-storage.h	Sun Jun 15 05:22:28 2003 +0300
+++ b/src/lib-storage/mail-storage.h	Sun Jun 15 06:42:28 2003 +0300
@@ -93,6 +93,11 @@
 	MAIL_FETCH_IMAP_ENVELOPE	= 0x4000
 };
 
+enum mail_sync_flags {
+	MAIL_SYNC_FLAG_NO_EXPUNGES	= 0x01,
+	MAIL_SYNC_FLAG_FAST		= 0x02
+};
+
 enum client_workarounds {
 	WORKAROUND_OE6_FETCH_NO_NEWMAIL	= 0x01,
 	WORKAROUND_OUTLOOK_IDLE		= 0x02
@@ -225,9 +230,8 @@
 	int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
 			  struct mailbox_status *status);
 
-	/* Synchronize the mailbox. If sync_expunges is FALSE, everything
-	   but expunges are synced. */
-	int (*sync)(struct mailbox *box, int sync_expunges);
+	/* Synchronize the mailbox. */
+	int (*sync)(struct mailbox *box, enum mail_sync_flags flags);
 
 	/* Synchronize mailbox in background. It's done until this function is
 	   called with sync_type = MAILBOX_SYNC_NONE */