mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-24 07:14:04 +00:00
md-cluster: re-add capabilities
When "re-add" is writted to /sys/block/mdXX/md/dev-YYY/state, the clustered md: 1. Sends RE_ADD message with the desc_nr. Nodes receiving the message clear the Faulty bit in their respective rdev->flags. 2. The node initiating re-add, gathers the bitmaps of all nodes and copies them into the local bitmap. It does not clear the bitmap from which it is copying. 3. Initiating node schedules a md recovery to sync the devices. Signed-off-by: Guoqing Jiang <gqjiang@suse.com> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
a6da4ef85c
commit
97f6cd39da
5 changed files with 71 additions and 13 deletions
|
@ -1851,7 +1851,7 @@ EXPORT_SYMBOL_GPL(bitmap_load);
|
||||||
* to our bitmap
|
* to our bitmap
|
||||||
*/
|
*/
|
||||||
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
sector_t *low, sector_t *high)
|
sector_t *low, sector_t *high, bool clear_bits)
|
||||||
{
|
{
|
||||||
int rv = 0, i, j;
|
int rv = 0, i, j;
|
||||||
sector_t block, lo = 0, hi = 0;
|
sector_t block, lo = 0, hi = 0;
|
||||||
|
@ -1882,6 +1882,7 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clear_bits) {
|
||||||
bitmap_update_sb(bitmap);
|
bitmap_update_sb(bitmap);
|
||||||
/* Setting this for the ev_page should be enough.
|
/* Setting this for the ev_page should be enough.
|
||||||
* And we do not require both write_all and PAGE_DIRT either
|
* And we do not require both write_all and PAGE_DIRT either
|
||||||
|
@ -1890,6 +1891,7 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
|
set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
|
||||||
bitmap_write_all(bitmap);
|
bitmap_write_all(bitmap);
|
||||||
bitmap_unplug(bitmap);
|
bitmap_unplug(bitmap);
|
||||||
|
}
|
||||||
*low = lo;
|
*low = lo;
|
||||||
*high = hi;
|
*high = hi;
|
||||||
err:
|
err:
|
||||||
|
|
|
@ -263,7 +263,7 @@ void bitmap_daemon_work(struct mddev *mddev);
|
||||||
int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
||||||
int chunksize, int init);
|
int chunksize, int init);
|
||||||
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
sector_t *lo, sector_t *hi);
|
sector_t *lo, sector_t *hi, bool clear_bits);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,6 +73,7 @@ enum msg_type {
|
||||||
RESYNCING,
|
RESYNCING,
|
||||||
NEWDISK,
|
NEWDISK,
|
||||||
REMOVE,
|
REMOVE,
|
||||||
|
RE_ADD,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cluster_msg {
|
struct cluster_msg {
|
||||||
|
@ -253,7 +254,7 @@ static void recover_bitmaps(struct md_thread *thread)
|
||||||
str, ret);
|
str, ret);
|
||||||
goto clear_bit;
|
goto clear_bit;
|
||||||
}
|
}
|
||||||
ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi);
|
ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);
|
pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);
|
||||||
goto dlm_unlock;
|
goto dlm_unlock;
|
||||||
|
@ -412,6 +413,16 @@ static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg)
|
||||||
pr_warn("%s: %d Could not find disk(%d) to REMOVE\n", __func__, __LINE__, msg->raid_slot);
|
pr_warn("%s: %d Could not find disk(%d) to REMOVE\n", __func__, __LINE__, msg->raid_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void process_readd_disk(struct mddev *mddev, struct cluster_msg *msg)
|
||||||
|
{
|
||||||
|
struct md_rdev *rdev = md_find_rdev_nr_rcu(mddev, msg->raid_slot);
|
||||||
|
|
||||||
|
if (rdev && test_bit(Faulty, &rdev->flags))
|
||||||
|
clear_bit(Faulty, &rdev->flags);
|
||||||
|
else
|
||||||
|
pr_warn("%s: %d Could not find disk(%d) which is faulty", __func__, __LINE__, msg->raid_slot);
|
||||||
|
}
|
||||||
|
|
||||||
static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
|
static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
|
||||||
{
|
{
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
|
@ -436,6 +447,11 @@ static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
|
||||||
__func__, __LINE__, msg->slot);
|
__func__, __LINE__, msg->slot);
|
||||||
process_remove_disk(mddev, msg);
|
process_remove_disk(mddev, msg);
|
||||||
break;
|
break;
|
||||||
|
case RE_ADD:
|
||||||
|
pr_info("%s: %d Received RE_ADD from %d\n",
|
||||||
|
__func__, __LINE__, msg->slot);
|
||||||
|
process_readd_disk(mddev, msg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_warn("%s:%d Received unknown message from %d\n",
|
pr_warn("%s:%d Received unknown message from %d\n",
|
||||||
__func__, __LINE__, msg->slot);
|
__func__, __LINE__, msg->slot);
|
||||||
|
@ -883,6 +899,35 @@ static int remove_disk(struct mddev *mddev, struct md_rdev *rdev)
|
||||||
return __sendmsg(cinfo, &cmsg);
|
return __sendmsg(cinfo, &cmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gather_bitmaps(struct md_rdev *rdev)
|
||||||
|
{
|
||||||
|
int sn, err;
|
||||||
|
sector_t lo, hi;
|
||||||
|
struct cluster_msg cmsg;
|
||||||
|
struct mddev *mddev = rdev->mddev;
|
||||||
|
struct md_cluster_info *cinfo = mddev->cluster_info;
|
||||||
|
|
||||||
|
cmsg.type = RE_ADD;
|
||||||
|
cmsg.raid_slot = rdev->desc_nr;
|
||||||
|
err = sendmsg(cinfo, &cmsg);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) {
|
||||||
|
if (sn == (cinfo->slot_number - 1))
|
||||||
|
continue;
|
||||||
|
err = bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);
|
||||||
|
if (err) {
|
||||||
|
pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if ((hi > 0) && (lo < mddev->recovery_cp))
|
||||||
|
mddev->recovery_cp = lo;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static struct md_cluster_operations cluster_ops = {
|
static struct md_cluster_operations cluster_ops = {
|
||||||
.join = join,
|
.join = join,
|
||||||
.leave = leave,
|
.leave = leave,
|
||||||
|
@ -898,6 +943,7 @@ static struct md_cluster_operations cluster_ops = {
|
||||||
.add_new_disk_finish = add_new_disk_finish,
|
.add_new_disk_finish = add_new_disk_finish,
|
||||||
.new_disk_ack = new_disk_ack,
|
.new_disk_ack = new_disk_ack,
|
||||||
.remove_disk = remove_disk,
|
.remove_disk = remove_disk,
|
||||||
|
.gather_bitmaps = gather_bitmaps,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init cluster_init(void)
|
static int __init cluster_init(void)
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct md_cluster_operations {
|
||||||
int (*add_new_disk_finish)(struct mddev *mddev);
|
int (*add_new_disk_finish)(struct mddev *mddev);
|
||||||
int (*new_disk_ack)(struct mddev *mddev, bool ack);
|
int (*new_disk_ack)(struct mddev *mddev, bool ack);
|
||||||
int (*remove_disk)(struct mddev *mddev, struct md_rdev *rdev);
|
int (*remove_disk)(struct mddev *mddev, struct md_rdev *rdev);
|
||||||
|
int (*gather_bitmaps)(struct md_rdev *rdev);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _MD_CLUSTER_H */
|
#endif /* _MD_CLUSTER_H */
|
||||||
|
|
|
@ -2596,8 +2596,17 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
|
||||||
}
|
}
|
||||||
} else if (cmd_match(buf, "re-add")) {
|
} else if (cmd_match(buf, "re-add")) {
|
||||||
if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1)) {
|
if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1)) {
|
||||||
|
/* clear_bit is performed _after_ all the devices
|
||||||
|
* have their local Faulty bit cleared. If any writes
|
||||||
|
* happen in the meantime in the local node, they
|
||||||
|
* will land in the local bitmap, which will be synced
|
||||||
|
* by this node eventually
|
||||||
|
*/
|
||||||
|
if (!mddev_is_clustered(rdev->mddev) ||
|
||||||
|
(err = md_cluster_ops->gather_bitmaps(rdev)) == 0) {
|
||||||
clear_bit(Faulty, &rdev->flags);
|
clear_bit(Faulty, &rdev->flags);
|
||||||
err = add_bound_rdev(rdev);
|
err = add_bound_rdev(rdev);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue