From: NeilBrown <neilb@suse.de>
Subject: md/bitmap: Don't write bitmap while earlier writes might be in-fligh
Patch-mainline: not yet
References: bnc#771398

As we don't wait for writes to complete in bitmap_daemon_work, they
could still be in-flight when bitmap_unplug writes again.  Or when
bitmap_daemon_work tries to write again.
This can be confusing and could risk the wrong data being written last.

So make sure we wait for old writes to complete before new writes start.
In bitmap_unplug, always wait if anything is written as that is probably
always the case anyway.

Signed-off-by: Neil Brown <neilb@suse.de>

---
 drivers/md/bitmap.c |   32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

--- linux-3.0-SLE11-SP2-BTMU.orig/drivers/md/bitmap.c
+++ linux-3.0-SLE11-SP2-BTMU/drivers/md/bitmap.c
@@ -482,6 +482,13 @@ void bitmap_update_sb(struct bitmap *bit
 	sb->sectors_reserved = cpu_to_le32(bitmap->mddev->
 					   bitmap_info.space);
 	kunmap_atomic(sb, KM_USER0);
+	/* Don't write until any other writes have completed */
+	if (bitmap->storage.file)
+		wait_event(bitmap->write_wait,
+			   atomic_read(&bitmap->pending_writes)==0);
+	else
+		md_super_wait(bitmap->mddev);
+
 	write_page(bitmap, bitmap->storage.sb_page, 1);
 }
 
@@ -947,7 +954,7 @@ void bitmap_unplug(struct bitmap *bitmap
 {
 	unsigned long i;
 	int dirty, need_write;
-	int wait = 0;
+	int writing = 0;
 
 	if (!bitmap || !bitmap->storage.filemap ||
 	    test_bit(BITMAP_STALE, &bitmap->flags))
@@ -962,13 +969,23 @@ void bitmap_unplug(struct bitmap *bitmap
 		need_write = test_and_clear_page_attr(bitmap, i,
 						      BITMAP_PAGE_NEEDWRITE);
 		if (dirty || need_write) {
+			if (!writing) {
+				/* Need to ensure any prior writes from
+				 * bitmap_daemon_work have completed.
+				 * We don't want the writes racing.
+				 */
+				if (bitmap->storage.file)
+					wait_event(bitmap->write_wait,
+						   atomic_read(&bitmap->pending_writes)==0);
+				else
+					md_super_wait(bitmap->mddev);
+			}
 			clear_page_attr(bitmap, i, BITMAP_PAGE_PENDING);
 			write_page(bitmap, bitmap->storage.filemap[i], 0);
+			writing = 1;
 		}
-		if (dirty)
-			wait = 1;
 	}
-	if (wait) { /* if any writes were performed, we need to wait on them */
+	if (writing) { /* if any writes were performed, we need to wait on them */
 		if (bitmap->storage.file)
 			wait_event(bitmap->write_wait,
 				   atomic_read(&bitmap->pending_writes)==0);
@@ -1258,6 +1275,13 @@ void bitmap_daemon_work(mddev_t *mddev)
 	}
 	spin_unlock_irq(&counts->lock);
 
+	/* Make sure any prior writes have completed */
+	if (bitmap->storage.file)
+		wait_event(bitmap->write_wait,
+			   atomic_read(&bitmap->pending_writes)==0);
+	else
+		md_super_wait(bitmap->mddev);
+
 	/* Now start writeout on any page in NEEDWRITE that isn't DIRTY.
 	 * DIRTY pages need to be written by bitmap_unplug so it can wait
 	 * for them.
