mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-28 23:24:50 +00:00
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:
parent
7da3d20333
commit
b98938d16a
3 changed files with 93 additions and 10 deletions
|
@ -471,6 +471,7 @@ void bitmap_update_sb(struct bitmap *bitmap)
|
||||||
kunmap_atomic(sb);
|
kunmap_atomic(sb);
|
||||||
write_page(bitmap, bitmap->storage.sb_page, 1);
|
write_page(bitmap, bitmap->storage.sb_page, 1);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_update_sb);
|
||||||
|
|
||||||
/* print out the bitmap file superblock */
|
/* print out the bitmap file superblock */
|
||||||
void bitmap_print_sb(struct bitmap *bitmap)
|
void bitmap_print_sb(struct bitmap *bitmap)
|
||||||
|
@ -1727,7 +1728,7 @@ void bitmap_flush(struct mddev *mddev)
|
||||||
/*
|
/*
|
||||||
* free memory that was allocated
|
* free memory that was allocated
|
||||||
*/
|
*/
|
||||||
static void bitmap_free(struct bitmap *bitmap)
|
void bitmap_free(struct bitmap *bitmap)
|
||||||
{
|
{
|
||||||
unsigned long k, pages;
|
unsigned long k, pages;
|
||||||
struct bitmap_page *bp;
|
struct bitmap_page *bp;
|
||||||
|
@ -1761,6 +1762,7 @@ static void bitmap_free(struct bitmap *bitmap)
|
||||||
kfree(bp);
|
kfree(bp);
|
||||||
kfree(bitmap);
|
kfree(bitmap);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_free);
|
||||||
|
|
||||||
void bitmap_destroy(struct mddev *mddev)
|
void bitmap_destroy(struct mddev *mddev)
|
||||||
{
|
{
|
||||||
|
@ -1920,6 +1922,27 @@ int bitmap_load(struct mddev *mddev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(bitmap_load);
|
EXPORT_SYMBOL_GPL(bitmap_load);
|
||||||
|
|
||||||
|
struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot)
|
||||||
|
{
|
||||||
|
int rv = 0;
|
||||||
|
struct bitmap *bitmap;
|
||||||
|
|
||||||
|
bitmap = bitmap_create(mddev, slot);
|
||||||
|
if (IS_ERR(bitmap)) {
|
||||||
|
rv = PTR_ERR(bitmap);
|
||||||
|
return ERR_PTR(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = bitmap_init_from_disk(bitmap, 0);
|
||||||
|
if (rv) {
|
||||||
|
bitmap_free(bitmap);
|
||||||
|
return ERR_PTR(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(get_bitmap_from_slot);
|
||||||
|
|
||||||
/* Loads the bitmap associated with slot and copies the resync information
|
/* Loads the bitmap associated with slot and copies the resync information
|
||||||
* to our bitmap
|
* to our bitmap
|
||||||
*/
|
*/
|
||||||
|
@ -1929,14 +1952,13 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
int rv = 0, i, j;
|
int rv = 0, i, j;
|
||||||
sector_t block, lo = 0, hi = 0;
|
sector_t block, lo = 0, hi = 0;
|
||||||
struct bitmap_counts *counts;
|
struct bitmap_counts *counts;
|
||||||
struct bitmap *bitmap = bitmap_create(mddev, slot);
|
struct bitmap *bitmap;
|
||||||
|
|
||||||
if (IS_ERR(bitmap))
|
bitmap = get_bitmap_from_slot(mddev, slot);
|
||||||
return PTR_ERR(bitmap);
|
if (IS_ERR(bitmap)) {
|
||||||
|
pr_err("%s can't get bitmap from slot %d\n", __func__, slot);
|
||||||
rv = bitmap_init_from_disk(bitmap, 0);
|
return -1;
|
||||||
if (rv)
|
}
|
||||||
goto err;
|
|
||||||
|
|
||||||
counts = &bitmap->counts;
|
counts = &bitmap->counts;
|
||||||
for (j = 0; j < counts->chunks; j++) {
|
for (j = 0; j < counts->chunks; j++) {
|
||||||
|
@ -1963,8 +1985,7 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
||||||
bitmap_unplug(mddev->bitmap);
|
bitmap_unplug(mddev->bitmap);
|
||||||
*low = lo;
|
*low = lo;
|
||||||
*high = hi;
|
*high = hi;
|
||||||
err:
|
|
||||||
bitmap_free(bitmap);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(bitmap_copy_from_slot);
|
EXPORT_SYMBOL_GPL(bitmap_copy_from_slot);
|
||||||
|
|
|
@ -267,8 +267,10 @@ 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);
|
||||||
|
struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot);
|
||||||
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, bool clear_bits);
|
sector_t *lo, sector_t *hi, bool clear_bits);
|
||||||
|
void bitmap_free(struct bitmap *bitmap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1091,6 +1091,66 @@ static void metadata_update_cancel(struct mddev *mddev)
|
||||||
unlock_comm(cinfo);
|
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)
|
static int resync_start(struct mddev *mddev)
|
||||||
{
|
{
|
||||||
struct md_cluster_info *cinfo = mddev->cluster_info;
|
struct md_cluster_info *cinfo = mddev->cluster_info;
|
||||||
|
|
Loading…
Reference in a new issue