forked from mirrors/linux
		
	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