changeset 9201:4e74f4651f5b HEAD

OSX+Maildir: If readdir() fails with EINVAL after doing rename()s, retry. Fixes HFS+. Based on patch by Apple.
author Timo Sirainen <tss@iki.fi>
date Tue, 07 Jul 2009 21:42:06 -0400
parents 5d9eab092e97
children 797474444551
files src/lib-storage/index/maildir/maildir-sync.c
diffstat 1 files changed, 16 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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
@@ -355,7 +355,8 @@
 	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;
@@ -487,6 +488,14 @@
 		}
 	}
 
+#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);
@@ -520,7 +529,7 @@
 	}
 
 	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)
@@ -812,19 +821,20 @@
 		/* 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;
+		bool final = FALSE;
 
-		while ((ret = maildir_scan_dir(ctx, TRUE)) > 0) {
+		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;
 		}