Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
mdadm.14070
0036-imsm-use-rounded-size-for-metadata-initial...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0036-imsm-use-rounded-size-for-metadata-initialization.patch of Package mdadm.14070
From b53bfba6119d3f6f56eb9e10e5a59da6901af159 Mon Sep 17 00:00:00 2001 From: Tomasz Majchrzak <tomasz.majchrzak@intel.com> Date: Thu, 30 Mar 2017 16:25:41 +0200 Subject: [PATCH] imsm: use rounded size for metadata initialization Array size is rounded to the nearest MB, however number of data stripes and blocks per disk are calculated using size passed by the user. If given size is not aligned, there is a mismatch. It's not possible to assemble raid0 migrated to raid5 since raid5 arrays use number of data stripes to calculate array size. Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com> Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> --- super-intel.c | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/super-intel.c b/super-intel.c index 785488a..84dfe2b 100644 --- a/super-intel.c +++ b/super-intel.c @@ -264,6 +264,8 @@ struct bbm_log { static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" }; #endif +#define BLOCKS_PER_KB (1024/512) + #define RAID_DISK_RESERVED_BLOCKS_IMSM_HI 2209 #define GEN_MIGR_AREA_SIZE 2048 /* General Migration Copy Area size in blocks */ @@ -1324,6 +1326,19 @@ static int is_journal(struct imsm_disk *disk) return (disk->status & JOURNAL_DISK) == JOURNAL_DISK; } +/* round array size down to closest MB and ensure it splits evenly + * between members + */ +static unsigned long long round_size_to_mb(unsigned long long size, unsigned int + disk_count) +{ + size /= disk_count; + size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; + size *= disk_count; + + return size; +} + /* try to determine how much space is reserved for metadata from * the last get_extents() entry on the smallest active disk, * otherwise fallback to the default @@ -3330,11 +3345,10 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, if (used_disks > 0) { array_blocks = blocks_per_member(map) * used_disks; - /* round array size down to closest MB - */ - info->custom_array_size = (array_blocks - >> SECT_PER_MB_SHIFT) - << SECT_PER_MB_SHIFT; + info->custom_array_size = + round_size_to_mb(array_blocks, + used_disks); + } } case MIGR_VERIFY: @@ -5241,6 +5255,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, unsigned long long array_blocks; size_t size_old, size_new; unsigned long long num_data_stripes; + unsigned int data_disks; + unsigned long long size_per_member; if (super->orom && mpb->num_raid_devs >= super->orom->vpa) { pr_err("This imsm-container already has the maximum of %d volumes\n", super->orom->vpa); @@ -5317,9 +5333,11 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN); array_blocks = calc_array_size(info->level, info->raid_disks, info->layout, info->chunk_size, - s->size * 2); - /* round array size down to closest MB */ - array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; + s->size * BLOCKS_PER_KB); + data_disks = get_data_disks(info->level, info->layout, + info->raid_disks); + array_blocks = round_size_to_mb(array_blocks, data_disks); + size_per_member = array_blocks / data_disks; dev->size_low = __cpu_to_le32((__u32) array_blocks); dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32)); @@ -5331,7 +5349,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, vol->curr_migr_unit = 0; map = get_imsm_map(dev, MAP_0); set_pba_of_lba0(map, super->create_offset); - set_blocks_per_member(map, info_to_blocks_per_member(info, s->size)); + set_blocks_per_member(map, info_to_blocks_per_member(info, + size_per_member / + BLOCKS_PER_KB)); map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info)); map->failed_disk_num = ~0; if (info->level > 0) @@ -5359,7 +5379,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, map->num_domains = 1; /* info->size is only int so use the 'size' parameter instead */ - num_data_stripes = (s->size * 2) / info_to_blocks_per_strip(info); + num_data_stripes = size_per_member / info_to_blocks_per_strip(info); num_data_stripes /= map->num_domains; set_num_data_stripes(map, num_data_stripes); @@ -7981,9 +8001,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev, array_blocks = new_size; } - /* round array size down to closest MB - */ - array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; + array_blocks = round_size_to_mb(array_blocks, used_disks); dev->size_low = __cpu_to_le32((__u32)array_blocks); dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32)); @@ -8096,11 +8114,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent) array_blocks = blocks_per_member(map) * used_disks; - /* round array size down to closest MB - */ - array_blocks = (array_blocks - >> SECT_PER_MB_SHIFT) - << SECT_PER_MB_SHIFT; + array_blocks = + round_size_to_mb(array_blocks, + used_disks); a->info.custom_array_size = array_blocks; /* encourage manager to update array * size -- 2.10.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor