isw: array length calculation seems to be wrong

Dan Williams dan.j.williams at intel.com
Fri Jul 15 22:29:42 UTC 2011


On 7/13/2011 8:07 AM, Phillip Susi wrote:
> I'm trying to help a user with a problem with their isw set.  After
> upgrading to Ubuntu 11.04 ( 1.0.0.rc16 ) it seems that their partition
> extends beyond the end of the raid array.  I'm looking at how isw
> computes the array length and it seems to be wrong.  It looks like
> _cal_array_size() computes the length of the ( raid1 ) array by finding
> the smallest component disk and subtracting some reserved blocks.  This
> does not seem to be correct.  Relevant fields from the user's metadata:
>
> 0x0e8 disk[0].totalBlocks: 1953523055
> 0x118 disk[1].totalBlocks: 1953525168
> 0x148 isw_dev[0].SizeLow: 1953519616
> 0x1ac isw_dev[0].vol.map[0].blocks_per_member: 1953519880
> 0x1b0 isw_dev[0].vol.map[0].num_data_stripes: 7630936
> 0x1b4 isw_dev[0].vol.map[0].blocks_per_strip: 128
>
> Further, it looks like create_rd() sets the size of each component disk
> to the same thing anyhow:
>
> if ((r->sectors = dev->vol.map[0].blocks_per_member - RAID_DS_JOURNAL))
>
> This seems to have given the user a block device with a total size of
> 1953519880 sectors.  Debian and Ubuntu are carrying a patch that removes
> the subtraction of RAID_DS_JOURNAL above, or the array would be even
> smaller.  This seems to have been added because a Debian user had a
> similar shrinkage of their disk after an upgrade.  As you can see, the
> array size seems to be exactly equal to blocks_per_member, even though
> _cal_array_size() appears to be subtracting DISK_RESERVED_BLOCKS, which
> should make it a few hundred sectors smaller.  I am not sure why this is.
>
> I believe that the array size should be correctly computed as
> blocks_per_strip * num_data_stripes.  That appears to be off by a factor
> of two however, so maybe blocks_per_strip is actually in kb instead of
> sectors?  Correcting for that gives an array length of 1953519616
> sectors.  This matches isw_dev[0].SizeLow.  Perhaps this field should be
> used directly since it gives the correct size, instead of doing any
> calculations?

The size as understood by the BIOS is isw_dev[0].SizeLow (which is in 
sectors).

It happens to be the 1MB rounded down value of blocks_per_strip * 
num_data_stripes.

See the following commits:
http://neil.brown.name/git?p=mdadm;a=commitdiff;h=da9b4a62af80edbbcc96196ab5d887308516ba70

http://neil.brown.name/git?p=mdadm;a=commitdiff;h=979d38be50e84b70e0809249a6b05864049fb97d




More information about the Ataraid-list mailing list