summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGuoqing Jiang <gqjiang@suse.com>2015-12-21 10:50:59 +1100
committerNeilBrown <neilb@suse.com>2016-01-06 11:38:36 +1100
commit659b254fa7392e32b59a30d4b61fb12c4cd440ff (patch)
tree7e9a11ac79c881e7b6f712e804d35fda95cfbb07 /drivers
parentac277c6a8a39bc50f891a3477625330c276bd7f5 (diff)
md-cluster: remove a disk asynchronously from cluster environment
For cluster raid, if one disk couldn't be reach in one node, then other nodes would receive the REMOVE message for the disk. In receiving node, we can't call md_kick_rdev_from_array to remove the disk from array synchronously since the disk might still be busy in this node. So let's set a ClusterRemove flag on the disk, then let the thread to do the removal job eventually. Signed-off-by: Guoqing Jiang <gqjiang@suse.com> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Signed-off-by: NeilBrown <neilb@suse.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/md-cluster.c7
-rw-r--r--drivers/md/md.c12
-rw-r--r--drivers/md/md.h1
3 files changed, 18 insertions, 2 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index e57bbfed1638..3fd7301fd7af 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -440,8 +440,11 @@ static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg)
struct md_rdev *rdev = md_find_rdev_nr_rcu(mddev,
le32_to_cpu(msg->raid_slot));
- if (rdev)
- md_kick_rdev_from_array(rdev);
+ if (rdev) {
+ set_bit(ClusterRemove, &rdev->flags);
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
+ }
else
pr_warn("%s: %d Could not find disk(%d) to REMOVE\n",
__func__, __LINE__, le32_to_cpu(msg->raid_slot));
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 61aacab424cf..198e29dffb98 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8318,6 +8318,18 @@ void md_check_recovery(struct mddev *mddev)
goto unlock;
}
+ if (mddev_is_clustered(mddev)) {
+ struct md_rdev *rdev;
+ /* kick the device if another node issued a
+ * remove disk.
+ */
+ rdev_for_each(rdev, mddev) {
+ if (test_and_clear_bit(ClusterRemove, &rdev->flags) &&
+ rdev->raid_disk < 0)
+ md_kick_rdev_from_array(rdev);
+ }
+ }
+
if (!mddev->external) {
int did_change = 0;
spin_lock(&mddev->lock);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index ca0b643fe3c1..f7b17aef837d 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -183,6 +183,7 @@ enum flag_bits {
* Usually, this device should be faster
* than other devices in the array
*/
+ ClusterRemove,
};
#define BB_LEN_MASK (0x00000000000001FFULL)