changeset 5214:4e9d345df846 HEAD

When syncing huge maildirs check once in a while if we need to update dovecot-uidlist.lock so that another process won't decide that it's stale and overwrite it. Check more often when moving mails from new/ to cur/.
author Timo Sirainen <tss@iki.fi>
date Tue, 06 Mar 2007 17:39:04 +0200
parents 2969edccb9b0
children 9914a148eea1
files src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-storage.h src/lib-storage/index/maildir/maildir-sync.c
diffstat 3 files changed, 32 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-storage.c	Tue Mar 06 16:28:34 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Tue Mar 06 17:39:04 2007 +0200
@@ -20,9 +20,6 @@
 
 #define CREATE_MODE 0777 /* umask() should limit it more */
 
-/* How often to touch the uidlist lock file when using KEEP_LOCKED flag */
-#define MAILDIR_LOCK_TOUCH_MSECS (10*1000)
-
 #define MAILDIR_PLUSPLUS_DRIVER_NAME "maildir++"
 #define MAILDIR_SUBFOLDER_FILENAME "maildirfolder"
 
@@ -455,7 +452,7 @@
 			mailbox_close(&box);
 			return NULL;
 		}
-		mbox->keep_lock_to = timeout_add(MAILDIR_LOCK_TOUCH_MSECS,
+		mbox->keep_lock_to = timeout_add(MAILDIR_LOCK_TOUCH_SECS * 1000,
 						 maildir_lock_touch_timeout,
 						 mbox);
 	}
--- a/src/lib-storage/index/maildir/maildir-storage.h	Tue Mar 06 16:28:34 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Tue Mar 06 17:39:04 2007 +0200
@@ -34,6 +34,11 @@
 /* Delete files having ctime older than this from tmp/. 36h is standard. */
 #define MAILDIR_TMP_DELETE_SECS (36*60*60)
 
+/* How often to touch the uidlist lock file when it's locked.
+   This is done both when using KEEP_LOCKED flag and when syncing a large
+   maildir. */
+#define MAILDIR_LOCK_TOUCH_SECS 10
+
 #define MAILDIR_SAVE_FLAG_HARDLINK 0x10000000
 #define MAILDIR_SAVE_FLAG_DELETED  0x20000000
 
--- a/src/lib-storage/index/maildir/maildir-sync.c	Tue Mar 06 16:28:34 2007 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Tue Mar 06 17:39:04 2007 +0200
@@ -197,6 +197,13 @@
    bet here, but I guess 5 will do just fine too. */
 #define MAILDIR_RENAME_RESCAN_COUNT 5
 
+/* After moving 100 mails from new/ to cur/, check if we need to touch the
+   uidlist lock. */
+#define MAILDIR_SLOW_MOVE_COUNT 100
+/* readdir() should be pretty fast to do, but check anyway every 10000 mails
+   to see if we need to touch the uidlist lock. */
+#define MAILDIR_SLOW_CHECK_COUNT 10000
+
 struct maildir_sync_context {
         struct maildir_mailbox *mbox;
 	const char *new_dir, *cur_dir;
@@ -685,9 +692,12 @@
 	string_t *src, *dest;
 	struct dirent *dp;
 	enum maildir_uidlist_rec_flag flags;
-	unsigned int moves = 0;
+	time_t last_touch;
+	unsigned int moves = 0, count = 0;
 	int ret = 1;
-	bool move_new;
+	bool move_new, check_touch;
+
+	last_touch = ioloop_time;
 
 	dir = new_dir ? ctx->new_dir : ctx->cur_dir;
 	dirp = opendir(dir);
@@ -721,6 +731,7 @@
 		if (ret < 0)
 			break;
 
+		check_touch = FALSE;
 		flags = 0;
 		if (move_new) {
 			str_truncate(src, 0);
@@ -753,11 +764,24 @@
 					"rename(%s, %s) failed: %m",
 					str_c(src), str_c(dest));
 			}
+			if ((moves % MAILDIR_SLOW_MOVE_COUNT) == 0)
+				check_touch = TRUE;
 		} else if (new_dir) {
 			flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR |
 				MAILDIR_UIDLIST_REC_FLAG_RECENT;
 		}
 
+		count++;
+		if (check_touch || (count % MAILDIR_SLOW_CHECK_COUNT) == 0) {
+			time_t now = time(NULL);
+
+			if (now - last_touch > MAILDIR_LOCK_TOUCH_SECS) {
+				(void)maildir_uidlist_lock_touch(
+							ctx->mbox->uidlist);
+				last_touch = now;
+			}
+		}
+
 		ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
 						dp->d_name, flags);
 		if (ret <= 0) {