diff -aur dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain.c dovecot-2.2.10/src/doveadm/dsync/dsync-brain.c
--- dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain.c	2013-11-19 21:36:30.000000000 +0100
+++ dovecot-2.2.10/src/doveadm/dsync/dsync-brain.c	2014-01-17 15:37:31.136097108 +0100
@@ -113,6 +113,7 @@
 	brain->ibc = ibc;
 	brain->sync_type = DSYNC_BRAIN_SYNC_TYPE_UNKNOWN;
 	brain->lock_fd = -1;
+	brain->box_lock_fd = -1;
 	brain->verbose_proctitle = service_set->verbose_proctitle;
 	hash_table_create(&brain->mailbox_states, pool, 0,
 			  guid_128_hash, guid_128_cmp);
diff -aur dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain-mailbox.c dovecot-2.2.10/src/doveadm/dsync/dsync-brain-mailbox.c
--- dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain-mailbox.c	2013-12-19 22:05:18.000000000 +0100
+++ dovecot-2.2.10/src/doveadm/dsync/dsync-brain-mailbox.c	2014-01-17 17:54:53.905111604 +0100
@@ -40,6 +40,67 @@
 	return 1;
 }
 
+int dsync_brain_mailbox_lock(struct dsync_brain *brain, struct mailbox *box)
+{
+	struct stat st1, st2;
+	const char *control_dir;
+	
+	if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_CONTROL,
+				&control_dir) <= 0) {
+		i_error("Couldn't look up control dir");
+		return -1;
+	}
+
+	brain->box_lock_path = p_strconcat(brain->pool, control_dir,
+				       "/"DSYNC_BOX_LOCK_FILENAME, NULL);
+	for (;;) {
+		brain->box_lock_fd = creat(brain->box_lock_path, 0600);
+		if (brain->box_lock_fd == -1) {
+			i_error("Couldn't create lock %s: %m",
+				brain->box_lock_path);
+			return -1;
+		}
+
+		if (file_try_lock(brain->box_lock_fd, brain->box_lock_path, F_WRLCK,
+				   FILE_LOCK_METHOD_FCNTL, &brain->box_lock) <= 0) {
+			i_warning("Couldn't lock %s: %m", brain->box_lock_path);
+			break;
+		}
+		if (fstat(brain->box_lock_fd, &st1) < 0) {
+			if (errno != ESTALE) {
+				i_error("fstat(%s) failed: %m", brain->box_lock_path);
+				break;
+			}
+		} else if (stat(brain->box_lock_path, &st2) < 0) {
+			if (errno != ENOENT) {
+				i_error("stat(%s) failed: %m", brain->box_lock_path);
+				break;
+			}
+		} else if (st1.st_ino == st2.st_ino) {
+			/* success */
+			return 0;
+		}
+		/* file was recreated, try again */
+		i_close_fd(&brain->box_lock_fd);
+	}
+	i_close_fd(&brain->box_lock_fd);
+	brain->box_lock_fd = -1;
+	return -1;
+}
+
+void dsync_brain_mailbox_unlock(struct dsync_brain *brain)
+{
+	if (brain->box_lock_fd != -1) {
+		/* unlink the lock file before it gets unlocked */
+		if (unlink(brain->box_lock_path) < 0)
+			i_error("unlink(%s) failed: %m", brain->box_lock_path);
+		file_lock_free(&brain->box_lock);
+		i_close_fd(&brain->box_lock_fd);
+		brain->box_lock_fd = -1;
+	}
+}
+
+
 int dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid,
 			      struct mailbox **box_r, const char **error_r)
 {
@@ -269,6 +330,7 @@
 	if (brain->log_scan != NULL)
 		dsync_transaction_log_scan_deinit(&brain->log_scan);
 	mailbox_free(&brain->box);
+	dsync_brain_mailbox_unlock(brain);
 
 	brain->state = brain->pre_box_state;
 }
@@ -369,11 +431,17 @@
 		flags |= MAILBOX_FLAG_READONLY;
 	}
 	box = mailbox_alloc(node->ns->list, vname, flags);
+
+	if (dsync_brain_mailbox_lock(brain, box) < 0) {
+		return 0;
+	}
+
 	for (;;) {
 		if ((ret = dsync_box_get(box, &dsync_box)) <= 0) {
 			if (ret < 0)
 				brain->failed = TRUE;
 			mailbox_free(&box);
+			dsync_brain_mailbox_unlock(brain);
 			return ret;
 		}
 
@@ -381,6 +449,7 @@
 		   we can skip the mailbox */
 		if (!dsync_brain_has_mailbox_state_changed(brain, &dsync_box)) {
 			mailbox_free(&box);
+			dsync_brain_mailbox_unlock(brain);
 			return 0;
 		}
 		if (synced) {
@@ -396,6 +465,7 @@
 				mailbox_get_last_error(box, NULL));
 			brain->failed = TRUE;
 			mailbox_free(&box);
+			dsync_brain_mailbox_unlock(brain);
 			return -1;
 		}
 		synced = TRUE;
@@ -625,6 +695,7 @@
 		i_assert(brain->failed);
 		return TRUE;
 	}
+
 	if (box == NULL) {
 		/* mailbox was probably deleted/renamed during sync */
 		if (brain->backup_send && brain->no_backup_overwrite) {
@@ -648,17 +719,23 @@
 		dsync_brain_slave_send_mailbox_lost(brain, dsync_box);
 		return TRUE;
 	}
+	if (dsync_brain_mailbox_lock(brain, box) < 0) {
+		brain->failed = TRUE;
+		return TRUE;
+	}
 	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
 		i_error("Can't sync mailbox %s: %s",
 			mailbox_get_vname(box),
 			mailbox_get_last_error(box, NULL));
 		mailbox_free(&box);
+		dsync_brain_mailbox_unlock(brain);
 		brain->failed = TRUE;
 		return TRUE;
 	}
 
 	if ((ret = dsync_box_get(box, &local_dsync_box)) <= 0) {
 		mailbox_free(&box);
+		dsync_brain_mailbox_unlock(brain);
 		if (ret < 0) {
 			brain->failed = TRUE;
 			return TRUE;
@@ -677,6 +754,7 @@
 	if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box)) {
 		/* no fields appear to have changed, skip this mailbox */
 		mailbox_free(&box);
+		dsync_brain_mailbox_unlock(brain);
 		return TRUE;
 	}
 
diff -aur dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain-private.h dovecot-2.2.10/src/doveadm/dsync/dsync-brain-private.h
--- dovecot-2.2.10.old/src/doveadm/dsync/dsync-brain-private.h	2013-11-19 21:36:30.000000000 +0100
+++ dovecot-2.2.10/src/doveadm/dsync/dsync-brain-private.h	2014-01-17 17:49:35.109122642 +0100
@@ -7,6 +7,7 @@
 #include "dsync-mailbox-state.h"
 
 #define DSYNC_LOCK_FILENAME ".dovecot-sync.lock"
+#define DSYNC_BOX_LOCK_FILENAME "dovecot-sync.lock"
 
 struct dsync_mailbox_tree_sync_change;
 
@@ -60,6 +61,10 @@
 	const char *lock_path;
 	struct file_lock *lock;
 
+	int box_lock_fd;
+	char *box_lock_path;
+	struct file_lock *box_lock;
+
 	char hierarchy_sep;
 	struct dsync_mailbox_tree *local_mailbox_tree;
 	struct dsync_mailbox_tree *remote_mailbox_tree;
