diff options
-rw-r--r-- | drivers/md/bitmap.c | 20 | ||||
-rw-r--r-- | drivers/md/bitmap.h | 2 | ||||
-rw-r--r-- | drivers/md/md-cluster.c | 48 | ||||
-rw-r--r-- | drivers/md/md-cluster.h | 1 | ||||
-rw-r--r-- | drivers/md/md.c | 13 |
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 | */ |
1853 | int bitmap_copy_from_slot(struct mddev *mddev, int slot, | 1853 | int 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; |
1895 | err: | 1897 | err: |
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); | |||
263 | int bitmap_resize(struct bitmap *bitmap, sector_t blocks, | 263 | int bitmap_resize(struct bitmap *bitmap, sector_t blocks, |
264 | int chunksize, int init); | 264 | int chunksize, int init); |
265 | int bitmap_copy_from_slot(struct mddev *mddev, int slot, | 265 | int 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 | ||
78 | struct cluster_msg { | 79 | struct 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 | ||
416 | static 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 | |||
415 | static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) | 426 | static 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 | ||
902 | static 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 | } | ||
927 | out: | ||
928 | return err; | ||
929 | } | ||
930 | |||
886 | static struct md_cluster_operations cluster_ops = { | 931 | static 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 | ||
903 | static int __init cluster_init(void) | 949 | static 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 | } |