[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c, 1.55, 1.56

cras at dovecot.org cras at dovecot.org
Thu Jun 16 22:46:20 EEST 2005


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

Modified Files:
	maildir-sync.c 
Log Message:
If we have rename()d more than 5 files from new/ to cur/, rescan the
directory again to make sure we didn't skip any files.



Index: maildir-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- maildir-sync.c	9 Jun 2005 14:31:43 -0000	1.55
+++ maildir-sync.c	16 Jun 2005 19:46:18 -0000	1.56
@@ -188,6 +188,14 @@
 
 #define MAILDIR_FILENAME_FLAG_FOUND 128
 
+/* When rename()ing many files from new/ to cur/, it's possible that next
+   readdir() skips some files. we don't of course wish to lose them, so we
+   go and rescan the new/ directory again from beginning until no files are
+   left. This value is just an optimization to avoid checking the directory
+   twice unneededly. usually only NFS is the problem case. 1 is the safest
+   bet here, but I guess 5 will do just fine too. */
+#define MAILDIR_RENAME_RESCAN_COUNT 5
+
 struct maildir_sync_context {
         struct maildir_mailbox *mbox;
 	const char *new_dir, *cur_dir;
@@ -420,7 +428,8 @@
 	DIR *dirp;
 	string_t *src, *dest;
 	struct dirent *dp;
-        enum maildir_uidlist_rec_flag flags;
+	enum maildir_uidlist_rec_flag flags;
+	unsigned int moves = 0;
 	int move_new, ret = 1;
 
 	dir = new_dir ? ctx->new_dir : ctx->cur_dir;
@@ -466,11 +475,13 @@
 			}
 			if (rename(str_c(src), str_c(dest)) == 0) {
 				/* we moved it - it's \Recent for us */
-                                ctx->mbox->dirty_cur_time = ioloop_time;
+				moves++;
+				ctx->mbox->dirty_cur_time = ioloop_time;
 				flags |= MAILDIR_UIDLIST_REC_FLAG_MOVED |
 					MAILDIR_UIDLIST_REC_FLAG_RECENT;
 			} else if (ENOTFOUND(errno)) {
 				/* someone else moved it already */
+				moves++;
 				flags |= MAILDIR_UIDLIST_REC_FLAG_MOVED;
 			} else if (ENOSPACE(errno)) {
 				/* not enough disk space, leave here */
@@ -510,7 +521,7 @@
 	}
 
 	t_pop();
-	return ret < 0 ? -1 : 0;
+	return ret < 0 ? -1 : (moves <= MAILDIR_RENAME_RESCAN_COUNT ? 0 : 1);
 }
 
 static int maildir_sync_quick_check(struct maildir_sync_context *ctx,
@@ -937,7 +948,12 @@
 	ctx->uidlist_sync_ctx =
 		maildir_uidlist_sync_init(ctx->mbox->uidlist, ctx->partial);
 
-	if (maildir_scan_dir(ctx, TRUE) < 0)
+	while ((ret = maildir_scan_dir(ctx, TRUE)) > 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 (ret < 0)
 		return -1;
 	if (cur_changed) {
 		if (maildir_scan_dir(ctx, FALSE) < 0)



More information about the dovecot-cvs mailing list