aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bitmap.c20
-rw-r--r--drivers/md/bitmap.h2
-rw-r--r--drivers/md/md-cluster.c48
-rw-r--r--drivers/md/md-cluster.h1
-rw-r--r--drivers/md/md.c13
5 files changed, 71 insertions, 13 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index e98db04eb4f9..2bc56e2a3526 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1851,7 +1851,7 @@ EXPORT_SYMBOL_GPL(bitmap_load);
1851 * to our bitmap 1851 * to our bitmap
1852 */ 1852 */
1853int bitmap_copy_from_slot(struct mddev *mddev, int slot, 1853int bitmap_copy_from_slot(struct mddev *mddev, int slot,
1854 sector_t *low, sector_t *high) 1854 sector_t *low, sector_t *high, bool clear_bits)
1855{ 1855{
1856 int rv = 0, i, j; 1856 int rv = 0, i, j;
1857 sector_t block, lo = 0, hi = 0; 1857 sector_t block, lo = 0, hi = 0;
@@ -1882,14 +1882,16 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
1882 } 1882 }
1883 } 1883 }
1884 1884
1885 bitmap_update_sb(bitmap); 1885 if (clear_bits) {
1886 /* Setting this for the ev_page should be enough. 1886 bitmap_update_sb(bitmap);
1887 * And we do not require both write_all and PAGE_DIRT either 1887 /* Setting this for the ev_page should be enough.
1888 */ 1888 * And we do not require both write_all and PAGE_DIRT either
1889 for (i = 0; i < bitmap->storage.file_pages; i++) 1889 */
1890 set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY); 1890 for (i = 0; i < bitmap->storage.file_pages; i++)
1891 bitmap_write_all(bitmap); 1891 set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
1892 bitmap_unplug(bitmap); 1892 bitmap_write_all(bitmap);
1893 bitmap_unplug(bitmap);
1894 }
1893 *low = lo; 1895 *low = lo;
1894 *high = hi; 1896 *high = hi;
1895err: 1897err:
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
index 4aabc74ef7b9..f1f4dd01090d 100644
--- a/drivers/md/bitmap.h
+++ b/drivers/md/bitmap.h
@@ -263,7 +263,7 @@ void bitmap_daemon_work(struct mddev *mddev);
263int bitmap_resize(struct bitmap *bitmap, sector_t blocks, 263int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
264 int chunksize, int init); 264 int chunksize, int init);
265int bitmap_copy_from_slot(struct mddev *mddev, int slot, 265int bitmap_copy_from_slot(struct mddev *mddev, int slot,
266 sector_t *lo, sector_t *hi); 266 sector_t *lo, sector_t *hi, bool clear_bits);
267#endif 267#endif
268 268
269#endif 269#endif
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index 30b41b70db17..fcfc4b9b2672 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -73,6 +73,7 @@ enum msg_type {
73 RESYNCING, 73 RESYNCING,
74 NEWDISK, 74 NEWDISK,
75 REMOVE, 75 REMOVE,
76 RE_ADD,
76}; 77};
77 78
78struct cluster_msg { 79struct cluster_msg {
@@ -253,7 +254,7 @@ static void recover_bitmaps(struct md_thread *thread)
253 str, ret); 254 str, ret);
254 goto clear_bit; 255 goto clear_bit;
255 } 256 }
256 ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi); 257 ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);
257 if (ret) { 258 if (ret) {
258 pr_err("md-cluster: Could not copy data from bitmap %d\n", slot); 259 pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);
259 goto dlm_unlock; 260 goto dlm_unlock;
@@ -412,6 +413,16 @@ static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg)
412 pr_warn("%s: %d Could not find disk(%d) to REMOVE\n", __func__, __LINE__, msg->raid_slot); 413 pr_warn("%s: %d Could not find disk(%d) to REMOVE\n", __func__, __LINE__, msg->raid_slot);
413} 414}
414 415
416static void process_readd_disk(struct mddev *mddev, struct cluster_msg *msg)
417{
418 struct md_rdev *rdev = md_find_rdev_nr_rcu(mddev, msg->raid_slot);
419
420 if (rdev && test_bit(Faulty, &rdev->flags))
421 clear_bit(Faulty, &rdev->flags);
422 else
423 pr_warn("%s: %d Could not find disk(%d) which is faulty", __func__, __LINE__, msg->raid_slot);
424}
425
415static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) 426static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
416{ 427{
417 switch (msg->type) { 428 switch (msg->type) {
@@ -436,6 +447,11 @@ static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
436 __func__, __LINE__, msg->slot); 447 __func__, __LINE__, msg->slot);
437 process_remove_disk(mddev, msg); 448 process_remove_disk(mddev, msg);
438 break; 449 break;
450 case RE_ADD:
451 pr_info("%s: %d Received RE_ADD from %d\n",
452 __func__, __LINE__, msg->slot);
453 process_readd_disk(mddev, msg);
454 break;
439 default: 455 default:
440 pr_warn("%s:%d Received unknown message from %d\n", 456 pr_warn("%s:%d Received unknown message from %d\n",
441 __func__, __LINE__, msg->slot); 457 __func__, __LINE__, msg->slot);
@@ -883,6 +899,35 @@ static int remove_disk(struct mddev *mddev, struct md_rdev *rdev)
883 return __sendmsg(cinfo, &cmsg); 899 return __sendmsg(cinfo, &cmsg);
884} 900}
885 901
902static int gather_bitmaps(struct md_rdev *rdev)
903{
904 int sn, err;
905 sector_t lo, hi;
906 struct cluster_msg cmsg;
907 struct mddev *mddev = rdev->mddev;
908 struct md_cluster_info *cinfo = mddev->cluster_info;
909
910 cmsg.type = RE_ADD;
911 cmsg.raid_slot = rdev->desc_nr;
912 err = sendmsg(cinfo, &cmsg);
913 if (err)
914 goto out;
915
916 for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) {
917 if (sn == (cinfo->slot_number - 1))
918 continue;
919 err = bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);
920 if (err) {
921 pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn);
922 goto out;
923 }
924 if ((hi > 0) && (lo < mddev->recovery_cp))
925 mddev->recovery_cp = lo;
926 }
927out:
928 return err;
929}
930
886static struct md_cluster_operations cluster_ops = { 931static struct md_cluster_operations cluster_ops = {
887 .join = join, 932 .join = join,
888 .leave = leave, 933 .leave = leave,
@@ -898,6 +943,7 @@ static struct md_cluster_operations cluster_ops = {
898 .add_new_disk_finish = add_new_disk_finish, 943 .add_new_disk_finish = add_new_disk_finish,
899 .new_disk_ack = new_disk_ack, 944 .new_disk_ack = new_disk_ack,
900 .remove_disk = remove_disk, 945 .remove_disk = remove_disk,
946 .gather_bitmaps = gather_bitmaps,
901}; 947};
902 948
903static int __init cluster_init(void) 949static int __init cluster_init(void)
diff --git a/drivers/md/md-cluster.h b/drivers/md/md-cluster.h
index 71e51432c1f4..6817ee00e053 100644
--- a/drivers/md/md-cluster.h
+++ b/drivers/md/md-cluster.h
@@ -23,6 +23,7 @@ struct md_cluster_operations {
23 int (*add_new_disk_finish)(struct mddev *mddev); 23 int (*add_new_disk_finish)(struct mddev *mddev);
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}; 27};
27 28
28#endif /* _MD_CLUSTER_H */ 29#endif /* _MD_CLUSTER_H */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 429e95e9a942..d9cac48db2fc 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2596,8 +2596,17 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
2596 } 2596 }
2597 } else if (cmd_match(buf, "re-add")) { 2597 } else if (cmd_match(buf, "re-add")) {
2598 if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1)) { 2598 if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1)) {
2599 clear_bit(Faulty, &rdev->flags); 2599 /* clear_bit is performed _after_ all the devices
2600 err = add_bound_rdev(rdev); 2600 * have their local Faulty bit cleared. If any writes
2601 * happen in the meantime in the local node, they
2602 * will land in the local bitmap, which will be synced
2603 * by this node eventually
2604 */
2605 if (!mddev_is_clustered(rdev->mddev) ||
2606 (err = md_cluster_ops->gather_bitmaps(rdev)) == 0) {
2607 clear_bit(Faulty, &rdev->flags);
2608 err = add_bound_rdev(rdev);
2609 }
2601 } else 2610 } else
2602 err = -EBUSY; 2611 err = -EBUSY;
2603 } 2612 }