Re: isw: array length calculation seems to be wrong
Dan Williams <[email protected]> Fri, 15 Jul 2011 15:29:42 -0700
| Newsgroups | gmane.linux.ataraid |
|---|---|
| Message-ID | <[email protected]> |
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