md: perform async updates for metadata where possible.
authorNeilBrown <neilb@suse.com>
Fri, 4 Nov 2016 05:46:03 +0000 (16:46 +1100)
committerShaohua Li <shli@fb.com>
Mon, 7 Nov 2016 23:08:23 +0000 (15:08 -0800)
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 as
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: NeilBrown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/md.c

index 22c9efd86b0dd366bb4ce4374cc3fe2b9d66bb8f..f389d8abe137d377044a413a63c664850cc8bc97 100644 (file)
@@ -2599,8 +2599,10 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
 
                        if (err == 0) {
                                md_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);
                        }
                }
@@ -6175,7 +6177,11 @@ kick_rdev:
                md_cluster_ops->remove_disk(mddev, rdev);
 
        md_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;
@@ -6240,7 +6246,9 @@ static int hot_add_disk(struct mddev *mddev, dev_t dev)
 
        rdev->raid_disk = -1;
 
-       md_update_sb(mddev, 1);
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
+       if (!mddev->thread)
+               md_update_sb(mddev, 1);
        /*
         * Kick recovery, maybe this spare has to be added to the
         * array immediately.