dovecot-2.0: OSX+Maildir: If readdir() fails with EINVAL after d...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 8 04:42:28 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/b6fcd9966727
changeset: 9578:b6fcd9966727
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 07 21:42:06 2009 -0400
description:
OSX+Maildir: If readdir() fails with EINVAL after doing rename()s, retry. Fixes HFS+.
Based on patch by Apple.

diffstat:

1 file changed, 17 insertions(+), 7 deletions(-)
src/lib-storage/index/maildir/maildir-sync.c |   24 +++++++++++++++++-------

diffs (63 lines):

diff -r 44c2ba2ea75d -r b6fcd9966727 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Tue Jul 07 21:25:35 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Tue Jul 07 21:42:06 2009 -0400
@@ -356,7 +356,8 @@ maildir_stat(struct maildir_mailbox *mbo
 	return -1;
 }
 
-static int maildir_scan_dir(struct maildir_sync_context *ctx, bool new_dir)
+static int
+maildir_scan_dir(struct maildir_sync_context *ctx, bool new_dir, bool final)
 {
 	struct mail_storage *storage = &ctx->mbox->storage->storage;
 	const char *path;
@@ -488,6 +489,14 @@ static int maildir_scan_dir(struct maild
 		}
 	}
 
+#ifdef __APPLE__
+	if (errno == EINVAL && move_count > 0 && !final) {
+		/* OS X HFS+: readdir() fails sometimes when rename()
+		   have been done. */
+		move_count = MAILDIR_RENAME_RESCAN_COUNT + 1;
+	}
+#endif
+
 	if (errno != 0) {
 		mail_storage_set_critical(storage,
 					  "readdir(%s) failed: %m", path);
@@ -521,7 +530,7 @@ static int maildir_scan_dir(struct maild
 	}
 
 	return ret < 0 ? -1 :
-		(move_count <= MAILDIR_RENAME_RESCAN_COUNT ? 0 : 1);
+		(move_count <= MAILDIR_RENAME_RESCAN_COUNT || final ? 0 : 1);
 }
 
 int maildir_sync_header_refresh(struct maildir_mailbox *mbox)
@@ -815,19 +824,20 @@ static int maildir_sync_context(struct m
 		/* if we're going to check cur/ dir our current logic requires
 		   that new/ dir is checked as well. it's a good idea anyway. */
 		unsigned int count = 0;
-
-		while ((ret = maildir_scan_dir(ctx, TRUE)) > 0) {
+		bool final = FALSE;
+
+		while ((ret = maildir_scan_dir(ctx, TRUE, final)) > 0) {
 			/* rename()d at least some files, which might have
 			   caused some other files to be missed. check again
 			   (see MAILDIR_RENAME_RESCAN_COUNT). */
-			if (++count > MAILDIR_SCAN_DIR_MAX_COUNT)
-				break;
+			if (++count >= MAILDIR_SCAN_DIR_MAX_COUNT)
+				final = TRUE;
 		}
 		if (ret < 0)
 			return -1;
 
 		if (cur_changed) {
-			if (maildir_scan_dir(ctx, FALSE) < 0)
+			if (maildir_scan_dir(ctx, FALSE, TRUE) < 0)
 				return -1;
 		}
 


More information about the dovecot-cvs mailing list