aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuoqing Jiang <gqjiang@suse.com>2015-12-20 18:51:00 -0500
committerNeilBrown <neilb@suse.com>2016-01-05 19:38:57 -0500
commitf6a2dc64ee74477c966f5220b1f560ed6308d010 (patch)
treeb371e1cbeb71c2e04e45be01c4964faace6ec400
parent09afd2a8d6ad2c40f3c1ae0b3f83784864cf4c15 (diff)
md-cluster: append some actions when change bitmap from clustered to none
For clustered raid, we need to do extra actions when change bitmap to none. 1. check if all the bitmap lock could be get or not, if yes then we can continue the change since cluster raid is only active in current node. Otherwise return fail and unlock the related bitmap locks 2. set nodes to 0 and then leave cluster environment. 3. release other nodes's bitmap lock. Signed-off-by: Guoqing Jiang <gqjiang@suse.com> Signed-off-by: NeilBrown <neilb@suse.com>
-rw-r--r--drivers/md/md-cluster.c57
-rw-r--r--drivers/md/md-cluster.h2
-rw-r--r--drivers/md/md.c13
3 files changed, 72 insertions, 0 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index b58374daff32..db9375f501ab 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -55,6 +55,7 @@ struct md_cluster_info {
55 int slot_number; 55 int slot_number;
56 struct completion completion; 56 struct completion completion;
57 struct dlm_lock_resource *bitmap_lockres; 57 struct dlm_lock_resource *bitmap_lockres;
58 struct dlm_lock_resource **other_bitmap_lockres;
58 struct dlm_lock_resource *resync_lockres; 59 struct dlm_lock_resource *resync_lockres;
59 struct list_head suspend_list; 60 struct list_head suspend_list;
60 spinlock_t suspend_lock; 61 spinlock_t suspend_lock;
@@ -803,6 +804,7 @@ static void resync_bitmap(struct mddev *mddev)
803 __func__, __LINE__, err); 804 __func__, __LINE__, err);
804} 805}
805 806
807static void unlock_all_bitmaps(struct mddev *mddev);
806static int leave(struct mddev *mddev) 808static int leave(struct mddev *mddev)
807{ 809{
808 struct md_cluster_info *cinfo = mddev->cluster_info; 810 struct md_cluster_info *cinfo = mddev->cluster_info;
@@ -823,6 +825,7 @@ static int leave(struct mddev *mddev)
823 lockres_free(cinfo->ack_lockres); 825 lockres_free(cinfo->ack_lockres);
824 lockres_free(cinfo->no_new_dev_lockres); 826 lockres_free(cinfo->no_new_dev_lockres);
825 lockres_free(cinfo->bitmap_lockres); 827 lockres_free(cinfo->bitmap_lockres);
828 unlock_all_bitmaps(mddev);
826 dlm_release_lockspace(cinfo->lockspace, 2); 829 dlm_release_lockspace(cinfo->lockspace, 2);
827 return 0; 830 return 0;
828} 831}
@@ -1000,6 +1003,58 @@ static int remove_disk(struct mddev *mddev, struct md_rdev *rdev)
1000 return sendmsg(cinfo, &cmsg); 1003 return sendmsg(cinfo, &cmsg);
1001} 1004}
1002 1005
1006static int lock_all_bitmaps(struct mddev *mddev)
1007{
1008 int slot, my_slot, ret, held = 1, i = 0;
1009 char str[64];
1010 struct md_cluster_info *cinfo = mddev->cluster_info;
1011
1012 cinfo->other_bitmap_lockres = kzalloc((mddev->bitmap_info.nodes - 1) *
1013 sizeof(struct dlm_lock_resource *),
1014 GFP_KERNEL);
1015 if (!cinfo->other_bitmap_lockres) {
1016 pr_err("md: can't alloc mem for other bitmap locks\n");
1017 return 0;
1018 }
1019
1020 my_slot = slot_number(mddev);
1021 for (slot = 0; slot < mddev->bitmap_info.nodes; slot++) {
1022 if (slot == my_slot)
1023 continue;
1024
1025 memset(str, '\0', 64);
1026 snprintf(str, 64, "bitmap%04d", slot);
1027 cinfo->other_bitmap_lockres[i] = lockres_init(mddev, str, NULL, 1);
1028 if (!cinfo->other_bitmap_lockres[i])
1029 return -ENOMEM;
1030
1031 cinfo->other_bitmap_lockres[i]->flags |= DLM_LKF_NOQUEUE;
1032 ret = dlm_lock_sync(cinfo->other_bitmap_lockres[i], DLM_LOCK_PW);
1033 if (ret)
1034 held = -1;
1035 i++;
1036 }
1037
1038 return held;
1039}
1040
1041static void unlock_all_bitmaps(struct mddev *mddev)
1042{
1043 struct md_cluster_info *cinfo = mddev->cluster_info;
1044 int i;
1045
1046 /* release other node's bitmap lock if they are existed */
1047 if (cinfo->other_bitmap_lockres) {
1048 for (i = 0; i < mddev->bitmap_info.nodes - 1; i++) {
1049 if (cinfo->other_bitmap_lockres[i]) {
1050 dlm_unlock_sync(cinfo->other_bitmap_lockres[i]);
1051 lockres_free(cinfo->other_bitmap_lockres[i]);
1052 }
1053 }
1054 kfree(cinfo->other_bitmap_lockres);
1055 }
1056}
1057
1003static int gather_bitmaps(struct md_rdev *rdev) 1058static int gather_bitmaps(struct md_rdev *rdev)
1004{ 1059{
1005 int sn, err; 1060 int sn, err;
@@ -1045,6 +1100,8 @@ static struct md_cluster_operations cluster_ops = {
1045 .new_disk_ack = new_disk_ack, 1100 .new_disk_ack = new_disk_ack,
1046 .remove_disk = remove_disk, 1101 .remove_disk = remove_disk,
1047 .gather_bitmaps = gather_bitmaps, 1102 .gather_bitmaps = gather_bitmaps,
1103 .lock_all_bitmaps = lock_all_bitmaps,
1104 .unlock_all_bitmaps = unlock_all_bitmaps,
1048}; 1105};
1049 1106
1050static int __init cluster_init(void) 1107static int __init cluster_init(void)
diff --git a/drivers/md/md-cluster.h b/drivers/md/md-cluster.h
index e75ea2613184..45ce6c97d8bd 100644
--- a/drivers/md/md-cluster.h
+++ b/drivers/md/md-cluster.h
@@ -24,6 +24,8 @@ struct md_cluster_operations {
24 int (*new_disk_ack)(struct mddev *mddev, bool ack); 24 int (*new_disk_ack)(struct mddev *mddev, bool ack);
25 int (*remove_disk)(struct mddev *mddev, struct md_rdev *rdev); 25 int (*remove_disk)(struct mddev *mddev, struct md_rdev *rdev);
26 int (*gather_bitmaps)(struct md_rdev *rdev); 26 int (*gather_bitmaps)(struct md_rdev *rdev);
27 int (*lock_all_bitmaps)(struct mddev *mddev);
28 void (*unlock_all_bitmaps)(struct mddev *mddev);
27}; 29};
28 30
29#endif /* _MD_CLUSTER_H */ 31#endif /* _MD_CLUSTER_H */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f2f855c203e5..495d8aa0a0d2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6599,6 +6599,19 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
6599 rv = -EINVAL; 6599 rv = -EINVAL;
6600 goto err; 6600 goto err;
6601 } 6601 }
6602 if (mddev->bitmap_info.nodes) {
6603 /* hold PW on all the bitmap lock */
6604 if (md_cluster_ops->lock_all_bitmaps(mddev) <= 0) {
6605 printk("md: can't change bitmap to none since the"
6606 " array is in use by more than one node\n");
6607 rv = -EPERM;
6608 md_cluster_ops->unlock_all_bitmaps(mddev);
6609 goto err;
6610 }
6611
6612 mddev->bitmap_info.nodes = 0;
6613 md_cluster_ops->leave(mddev);
6614 }
6602 mddev->pers->quiesce(mddev, 1); 6615 mddev->pers->quiesce(mddev, 1);
6603 bitmap_destroy(mddev); 6616 bitmap_destroy(mddev);
6604 mddev->pers->quiesce(mddev, 0); 6617 mddev->pers->quiesce(mddev, 0);