md-cluster: introduce cluster_check_sync_size
Support resize is a little complex for clustered raid, since we need to ensure all the nodes share the same knowledge about the size of raid. We achieve the goal by check the sync_size which is in each node's bitmap, we can only change the capacity after cluster_check_sync_size returns 0. Also, get_bitmap_from_slot is added to get a slot's bitmap. And we exported some funcs since they are used in cluster_check_sync_size(). We can also reuse get_bitmap_from_slot to remove redundant code existed in bitmap_copy_from_slot. Reviewed-by: NeilBrown <neilb@suse.com> Signed-off-by: Guoqing Jiang <gqjiang@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:

committed by
Shaohua Li

parent
7da3d20333
commit
b98938d16a
@@ -1091,6 +1091,66 @@ static void metadata_update_cancel(struct mddev *mddev)
|
||||
unlock_comm(cinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* return 0 if all the bitmaps have the same sync_size
|
||||
*/
|
||||
int cluster_check_sync_size(struct mddev *mddev)
|
||||
{
|
||||
int i, rv;
|
||||
bitmap_super_t *sb;
|
||||
unsigned long my_sync_size, sync_size = 0;
|
||||
int node_num = mddev->bitmap_info.nodes;
|
||||
int current_slot = md_cluster_ops->slot_number(mddev);
|
||||
struct bitmap *bitmap = mddev->bitmap;
|
||||
char str[64];
|
||||
struct dlm_lock_resource *bm_lockres;
|
||||
|
||||
sb = kmap_atomic(bitmap->storage.sb_page);
|
||||
my_sync_size = sb->sync_size;
|
||||
kunmap_atomic(sb);
|
||||
|
||||
for (i = 0; i < node_num; i++) {
|
||||
if (i == current_slot)
|
||||
continue;
|
||||
|
||||
bitmap = get_bitmap_from_slot(mddev, i);
|
||||
if (IS_ERR(bitmap)) {
|
||||
pr_err("can't get bitmap from slot %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can hold the bitmap lock of one node then
|
||||
* the slot is not occupied, update the sb.
|
||||
*/
|
||||
snprintf(str, 64, "bitmap%04d", i);
|
||||
bm_lockres = lockres_init(mddev, str, NULL, 1);
|
||||
if (!bm_lockres) {
|
||||
pr_err("md-cluster: Cannot initialize %s\n", str);
|
||||
lockres_free(bm_lockres);
|
||||
return -1;
|
||||
}
|
||||
bm_lockres->flags |= DLM_LKF_NOQUEUE;
|
||||
rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);
|
||||
if (!rv)
|
||||
bitmap_update_sb(bitmap);
|
||||
lockres_free(bm_lockres);
|
||||
|
||||
sb = kmap_atomic(bitmap->storage.sb_page);
|
||||
if (sync_size == 0)
|
||||
sync_size = sb->sync_size;
|
||||
else if (sync_size != sb->sync_size) {
|
||||
kunmap_atomic(sb);
|
||||
bitmap_free(bitmap);
|
||||
return -1;
|
||||
}
|
||||
kunmap_atomic(sb);
|
||||
bitmap_free(bitmap);
|
||||
}
|
||||
|
||||
return (my_sync_size == sync_size) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int resync_start(struct mddev *mddev)
|
||||
{
|
||||
struct md_cluster_info *cinfo = mddev->cluster_info;
|
||||
|
Reference in New Issue
Block a user