From 6b8b3e8a8b3e62b4209eaa36697e3c9df457e196 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@cse.unsw.edu.au>
Date: Thu, 4 Aug 2005 12:53:35 -0700
Subject: [PATCH] [PATCH] md: make sure md bitmap updates are flushed when
 array is stopped.

The recent change to never ignore the bitmap, revealed that the bitmap isn't
begin flushed properly when an array is stopped.

We call bitmap_daemon_work three times as there is a three-stage pipeline for
flushing updates to the bitmap file.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 drivers/md/bitmap.c         | 23 +++++++++++++++++++++++
 drivers/md/md.c             |  2 ++
 include/linux/raid/bitmap.h |  1 +
 3 files changed, 26 insertions(+)

diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 09d32db06d2000..41df4cda66e2f2 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1450,6 +1450,29 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
 
 }
 
+/*
+ * flush out any pending updates
+ */
+void bitmap_flush(mddev_t *mddev)
+{
+	struct bitmap *bitmap = mddev->bitmap;
+	int sleep;
+
+	if (!bitmap) /* there was no bitmap */
+		return;
+
+	/* run the daemon_work three time to ensure everything is flushed
+	 * that can be
+	 */
+	sleep = bitmap->daemon_sleep;
+	bitmap->daemon_sleep = 0;
+	bitmap_daemon_work(bitmap);
+	bitmap_daemon_work(bitmap);
+	bitmap_daemon_work(bitmap);
+	bitmap->daemon_sleep = sleep;
+	bitmap_update_sb(bitmap);
+}
+
 /*
  * free memory that was allocated
  */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9fd4dbea0d0d73..480f658db6f21f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1798,6 +1798,8 @@ static int do_md_stop(mddev_t * mddev, int ro)
 				goto out;
 			mddev->ro = 1;
 		} else {
+			bitmap_flush(mddev);
+			wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
 			if (mddev->ro)
 				set_disk_ro(disk, 0);
 			blk_queue_make_request(mddev->queue, md_fail_request);
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 6213e976eadedb..4bf1659f8aa87d 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -248,6 +248,7 @@ struct bitmap {
 
 /* these are used only by md/bitmap */
 int  bitmap_create(mddev_t *mddev);
+void bitmap_flush(mddev_t *mddev);
 void bitmap_destroy(mddev_t *mddev);
 int  bitmap_active(struct bitmap *bitmap);
 
-- 
GitLab