From: NeilBrown <neilb@suse.de>
Subject: md: perform async updates for metadata where possible.
Patch-mainline: no
References: bnc#768084

When adding devices to, or removing device from, an array we need to
update the metadata.  However we don't need to do it synchronously and
data integrity doesn't depend on these changes being recorded
instantly.  So avoid the synchronous call to md_update_sb and just set
a flag so that the thread will do it.

This can reduce the number of updates performed when lots of devices
are being added or removed.

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

---
 drivers/md/md.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

--- linux-3.0-SLE11-SP3.orig/drivers/md/md.c
+++ linux-3.0-SLE11-SP3/drivers/md/md.c
@@ -2619,8 +2619,10 @@ state_store(mdk_rdev_t *rdev, const char
 		else {
 			mddev_t *mddev = rdev->mddev;
 			kick_rdev_from_array(rdev);
-			if (mddev->pers)
-				md_update_sb(mddev, 1);
+			if (mddev->pers) {
+				set_bit(MD_CHANGE_DEVS, &mddev->flags);
+				md_wakeup_thread(mddev->thread);
+			}
 			md_new_event(mddev);
 			err = 0;
 		}
@@ -5657,7 +5659,7 @@ static int add_new_disk(mddev_t * mddev,
 		else
 			sysfs_notify_dirent_safe(rdev->sysfs_state);
 
-		md_update_sb(mddev, 1);
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		if (mddev->degraded)
 			set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -5730,7 +5732,11 @@ static int hot_remove_disk(mddev_t * mdd
 		goto busy;
 
 	kick_rdev_from_array(rdev);
-	md_update_sb(mddev, 1);
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	if (mddev->thread)
+		md_wakeup_thread(mddev->thread);
+	else
+		md_update_sb(mddev, 1);
 	md_new_event(mddev);
 
 	return 0;
