|
|
2c1b57 |
commit b53bfba6119d3f6f56eb9e10e5a59da6901af159
|
|
|
2c1b57 |
Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
|
|
|
2c1b57 |
Date: Thu Mar 30 16:25:41 2017 +0200
|
|
|
2c1b57 |
|
|
|
2c1b57 |
imsm: use rounded size for metadata initialization
|
|
|
2c1b57 |
|
|
|
2c1b57 |
Array size is rounded to the nearest MB, however number of data stripes
|
|
|
2c1b57 |
and blocks per disk are calculated using size passed by the user. If
|
|
|
2c1b57 |
given size is not aligned, there is a mismatch. It's not possible to
|
|
|
2c1b57 |
assemble raid0 migrated to raid5 since raid5 arrays use number of data
|
|
|
2c1b57 |
stripes to calculate array size.
|
|
|
2c1b57 |
|
|
|
2c1b57 |
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
|
|
|
2c1b57 |
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
|
|
|
2c1b57 |
|
|
|
2c1b57 |
diff --git a/super-intel.c b/super-intel.c
|
|
|
2c1b57 |
index 785488a..84dfe2b 100644
|
|
|
2c1b57 |
--- a/super-intel.c
|
|
|
2c1b57 |
+++ b/super-intel.c
|
|
|
2c1b57 |
@@ -264,6 +264,8 @@ struct bbm_log {
|
|
|
2c1b57 |
static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
|
|
|
2c1b57 |
#endif
|
|
|
2c1b57 |
|
|
|
2c1b57 |
+#define BLOCKS_PER_KB (1024/512)
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
#define RAID_DISK_RESERVED_BLOCKS_IMSM_HI 2209
|
|
|
2c1b57 |
|
|
|
2c1b57 |
#define GEN_MIGR_AREA_SIZE 2048 /* General Migration Copy Area size in blocks */
|
|
|
2c1b57 |
@@ -1324,6 +1326,19 @@ static int is_journal(struct imsm_disk *disk)
|
|
|
2c1b57 |
return (disk->status & JOURNAL_DISK) == JOURNAL_DISK;
|
|
|
2c1b57 |
}
|
|
|
2c1b57 |
|
|
|
2c1b57 |
+/* round array size down to closest MB and ensure it splits evenly
|
|
|
2c1b57 |
+ * between members
|
|
|
2c1b57 |
+ */
|
|
|
2c1b57 |
+static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
|
|
|
2c1b57 |
+ disk_count)
|
|
|
2c1b57 |
+{
|
|
|
2c1b57 |
+ size /= disk_count;
|
|
|
2c1b57 |
+ size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
|
|
2c1b57 |
+ size *= disk_count;
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
+ return size;
|
|
|
2c1b57 |
+}
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
/* try to determine how much space is reserved for metadata from
|
|
|
2c1b57 |
* the last get_extents() entry on the smallest active disk,
|
|
|
2c1b57 |
* otherwise fallback to the default
|
|
|
2c1b57 |
@@ -3330,11 +3345,10 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
|
|
2c1b57 |
if (used_disks > 0) {
|
|
|
2c1b57 |
array_blocks = blocks_per_member(map) *
|
|
|
2c1b57 |
used_disks;
|
|
|
2c1b57 |
- /* round array size down to closest MB
|
|
|
2c1b57 |
- */
|
|
|
2c1b57 |
- info->custom_array_size = (array_blocks
|
|
|
2c1b57 |
- >> SECT_PER_MB_SHIFT)
|
|
|
2c1b57 |
- << SECT_PER_MB_SHIFT;
|
|
|
2c1b57 |
+ info->custom_array_size =
|
|
|
2c1b57 |
+ round_size_to_mb(array_blocks,
|
|
|
2c1b57 |
+ used_disks);
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
}
|
|
|
2c1b57 |
}
|
|
|
2c1b57 |
case MIGR_VERIFY:
|
|
|
2c1b57 |
@@ -5241,6 +5255,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
|
2c1b57 |
unsigned long long array_blocks;
|
|
|
2c1b57 |
size_t size_old, size_new;
|
|
|
2c1b57 |
unsigned long long num_data_stripes;
|
|
|
2c1b57 |
+ unsigned int data_disks;
|
|
|
2c1b57 |
+ unsigned long long size_per_member;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
if (super->orom && mpb->num_raid_devs >= super->orom->vpa) {
|
|
|
2c1b57 |
pr_err("This imsm-container already has the maximum of %d volumes\n", super->orom->vpa);
|
|
|
2c1b57 |
@@ -5317,9 +5333,11 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
|
2c1b57 |
strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
|
|
|
2c1b57 |
array_blocks = calc_array_size(info->level, info->raid_disks,
|
|
|
2c1b57 |
info->layout, info->chunk_size,
|
|
|
2c1b57 |
- s->size * 2);
|
|
|
2c1b57 |
- /* round array size down to closest MB */
|
|
|
2c1b57 |
- array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
|
|
2c1b57 |
+ s->size * BLOCKS_PER_KB);
|
|
|
2c1b57 |
+ data_disks = get_data_disks(info->level, info->layout,
|
|
|
2c1b57 |
+ info->raid_disks);
|
|
|
2c1b57 |
+ array_blocks = round_size_to_mb(array_blocks, data_disks);
|
|
|
2c1b57 |
+ size_per_member = array_blocks / data_disks;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
dev->size_low = __cpu_to_le32((__u32) array_blocks);
|
|
|
2c1b57 |
dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
|
|
|
2c1b57 |
@@ -5331,7 +5349,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
|
2c1b57 |
vol->curr_migr_unit = 0;
|
|
|
2c1b57 |
map = get_imsm_map(dev, MAP_0);
|
|
|
2c1b57 |
set_pba_of_lba0(map, super->create_offset);
|
|
|
2c1b57 |
- set_blocks_per_member(map, info_to_blocks_per_member(info, s->size));
|
|
|
2c1b57 |
+ set_blocks_per_member(map, info_to_blocks_per_member(info,
|
|
|
2c1b57 |
+ size_per_member /
|
|
|
2c1b57 |
+ BLOCKS_PER_KB));
|
|
|
2c1b57 |
map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
|
|
|
2c1b57 |
map->failed_disk_num = ~0;
|
|
|
2c1b57 |
if (info->level > 0)
|
|
|
2c1b57 |
@@ -5359,7 +5379,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
|
2c1b57 |
map->num_domains = 1;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
/* info->size is only int so use the 'size' parameter instead */
|
|
|
2c1b57 |
- num_data_stripes = (s->size * 2) / info_to_blocks_per_strip(info);
|
|
|
2c1b57 |
+ num_data_stripes = size_per_member / info_to_blocks_per_strip(info);
|
|
|
2c1b57 |
num_data_stripes /= map->num_domains;
|
|
|
2c1b57 |
set_num_data_stripes(map, num_data_stripes);
|
|
|
2c1b57 |
|
|
|
2c1b57 |
@@ -7981,9 +8001,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
|
|
|
2c1b57 |
array_blocks = new_size;
|
|
|
2c1b57 |
}
|
|
|
2c1b57 |
|
|
|
2c1b57 |
- /* round array size down to closest MB
|
|
|
2c1b57 |
- */
|
|
|
2c1b57 |
- array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
|
|
2c1b57 |
+ array_blocks = round_size_to_mb(array_blocks, used_disks);
|
|
|
2c1b57 |
dev->size_low = __cpu_to_le32((__u32)array_blocks);
|
|
|
2c1b57 |
dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
|
|
|
2c1b57 |
|
|
|
2c1b57 |
@@ -8096,11 +8114,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
|
|
|
2c1b57 |
array_blocks =
|
|
|
2c1b57 |
blocks_per_member(map) *
|
|
|
2c1b57 |
used_disks;
|
|
|
2c1b57 |
- /* round array size down to closest MB
|
|
|
2c1b57 |
- */
|
|
|
2c1b57 |
- array_blocks = (array_blocks
|
|
|
2c1b57 |
- >> SECT_PER_MB_SHIFT)
|
|
|
2c1b57 |
- << SECT_PER_MB_SHIFT;
|
|
|
2c1b57 |
+ array_blocks =
|
|
|
2c1b57 |
+ round_size_to_mb(array_blocks,
|
|
|
2c1b57 |
+ used_disks);
|
|
|
2c1b57 |
a->info.custom_array_size = array_blocks;
|
|
|
2c1b57 |
/* encourage manager to update array
|
|
|
2c1b57 |
* size
|