[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c, 1.22, 1.23 maildir-uidlist.c, 1.23, 1.24 maildir-uidlist.h, 1.8, 1.9

cras at procontrol.fi cras at procontrol.fi
Mon May 24 05:47:25 EEST 2004


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

Modified Files:
	maildir-sync.c maildir-uidlist.c maildir-uidlist.h 
Log Message:
race condition fixes



Index: maildir-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- a/maildir-sync.c	24 May 2004 02:29:43 -0000	1.22
+++ b/maildir-sync.c	24 May 2004 02:47:23 -0000	1.23
@@ -629,15 +629,33 @@
 
 		if (seq > hdr->messages_count) {
 			if (uid < hdr->next_uid) {
-				/* message not in index, but next_uid header
-				   is updated? shouldn't really happen.. */
-				mail_storage_set_critical(ibox->box.storage,
-					"Maildir sync: UID < next_uid "
-					"(%u < %u, file = %s)",
-					uid, hdr->next_uid, filename);
-				mail_index_mark_corrupted(ibox->index);
-				ret = -1;
-				break;
+				/* most likely a race condition: we read the
+				   maildir, then someone else expunged messages
+				   and committed changes to index. so, this
+				   message shouldn't actually exist. mark it
+				   racy and check in next sync.
+
+				   the difference between this and the later
+				   check is that this one happens when messages
+				   are expunged from the end */
+				if ((uflags &
+				     MAILDIR_UIDLIST_REC_FLAG_RACING) != 0) {
+					mail_storage_set_critical(
+						ibox->box.storage,
+						"Maildir sync: UID < next_uid "
+						"(%u < %u, file = %s)",
+						uid, hdr->next_uid, filename);
+					mail_index_mark_corrupted(ibox->index);
+					ret = -1;
+					break;
+				}
+				ibox->dirty_cur_time = ioloop_time;
+				maildir_uidlist_add_flags(ibox->uidlist,
+					filename,
+					MAILDIR_UIDLIST_REC_FLAG_RACING);
+
+				seq--;
+				continue;
 			}
 
 			mail_index_append(trans, uid, &seq);
@@ -661,20 +679,9 @@
 			/* most likely a race condition: we read the
 			   maildir, then someone else expunged messages and
 			   committed changes to index. so, this message
-			   shouldn't actually exist. check to be sure.
-
-			   FIXME: we could avoid this stat() and just mark
-			   this check in the uidlist and check it at next
-			   sync.. */
-			struct stat st;
-			const char *str;
-
-			t_push();
-			str = t_strdup_printf("%s/%s",
-				(uflags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) ?
-				ctx->new_dir : ctx->cur_dir, filename);
-			if (stat(str, &st) == 0) {
-				t_pop();
+			   shouldn't actually exist. mark it racy and check
+			   in next sync. */
+			if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RACING) != 0) {
 				mail_storage_set_critical(ibox->box.storage,
 					"Maildir sync: UID inserted in the "
 					"middle of mailbox "
@@ -683,8 +690,11 @@
 				mail_index_mark_corrupted(ibox->index);
 				ret = -1;
 				break;
-			}
-			t_pop();
+			 }
+
+			ibox->dirty_cur_time = ioloop_time;
+			maildir_uidlist_add_flags(ibox->uidlist, filename,
+				MAILDIR_UIDLIST_REC_FLAG_RACING);
 
 			seq--;
 			continue;

Index: maildir-uidlist.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- a/maildir-uidlist.c	24 May 2004 02:30:10 -0000	1.23
+++ b/maildir-uidlist.c	24 May 2004 02:47:23 -0000	1.24
@@ -848,6 +848,18 @@
 	return ret;
 }
 
+void maildir_uidlist_add_flags(struct maildir_uidlist *uidlist,
+			       const char *filename,
+			       enum maildir_uidlist_rec_flag flags)
+{
+	struct maildir_uidlist_rec *rec;
+
+	rec = hash_lookup(uidlist->files, filename);
+	i_assert(rec != NULL);
+
+	rec->flags |= flags;
+}
+
 struct maildir_uidlist_iter_ctx *
 maildir_uidlist_iter_init(struct maildir_uidlist *uidlist)
 {

Index: maildir-uidlist.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- a/maildir-uidlist.h	24 May 2004 02:29:43 -0000	1.8
+++ b/maildir-uidlist.h	24 May 2004 02:47:23 -0000	1.9
@@ -7,7 +7,8 @@
 	MAILDIR_UIDLIST_REC_FLAG_NEW_DIR	= 0x01,
 	MAILDIR_UIDLIST_REC_FLAG_MOVED		= 0x02,
 	MAILDIR_UIDLIST_REC_FLAG_RECENT		= 0x04,
-	MAILDIR_UIDLIST_REC_FLAG_NONSYNCED	= 0x08
+	MAILDIR_UIDLIST_REC_FLAG_NONSYNCED	= 0x08,
+	MAILDIR_UIDLIST_REC_FLAG_RACING		= 0x10
 };
 
 int maildir_uidlist_try_lock(struct maildir_uidlist *uidlist);
@@ -47,6 +48,10 @@
 int maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx);
 int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx *ctx);
 
+void maildir_uidlist_add_flags(struct maildir_uidlist *uidlist,
+			       const char *filename,
+			       enum maildir_uidlist_rec_flag flags);
+
 /* List all maildir files. */
 struct maildir_uidlist_iter_ctx *
 maildir_uidlist_iter_init(struct maildir_uidlist *uidlist);



More information about the dovecot-cvs mailing list