diff options
author | NeilBrown <neilb@suse.de> | 2012-03-22 04:43:09 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-03-22 04:43:09 +0100 |
commit | d4633e06dfc01723911627fcb104af2ffb6f6a95 (patch) | |
tree | 7db047fd5928104a696385c45a277ca2e35dc87d | |
parent | __write_init_super_ddf(): Use posix_memalign() instead of static aligned buffer (diff) | |
download | mdadm-d4633e06dfc01723911627fcb104af2ffb6f6a95.tar.xz mdadm-d4633e06dfc01723911627fcb104af2ffb6f6a95.zip |
Examine: fix array size calculation for RAID10.
RAID10 arrays with an odd number of devices had the arraysize
reported wrongly by --examine due to a rounding error.
Reported-by: Chris Francy <zoredache@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | super0.c | 14 | ||||
-rw-r--r-- | super1.c | 14 |
2 files changed, 17 insertions, 11 deletions
@@ -114,7 +114,7 @@ static void examine_super0(struct supertype *st, char *homehost) c=map_num(pers, sb->level); printf(" Raid Level : %s\n", c?c:"-unknown-"); if ((int)sb->level > 0) { - int ddsks=0; + int ddsks = 0, ddsks_denom = 1; printf(" Used Dev Size : %d%s\n", sb->size, human_size((long long)sb->size<<10)); switch(sb->level) { @@ -122,11 +122,15 @@ static void examine_super0(struct supertype *st, char *homehost) case 4: case 5: ddsks = sb->raid_disks-1; break; case 6: ddsks = sb->raid_disks-2; break; - case 10: ddsks = sb->raid_disks / (sb->layout&255) / ((sb->layout>>8)&255); + case 10: ddsks = sb->raid_disks; + ddsks_denom = (sb->layout&255) * ((sb->layout>>8)&255); + } + if (ddsks) { + long long asize = sb->size; + asize = (asize << 10) * ddsks / ddsks_denom; + printf(" Array Size : %llu%s\n", + asize >> 10, human_size(asize)); } - if (ddsks) - printf(" Array Size : %llu%s\n", (unsigned long long)ddsks * sb->size, - human_size(ddsks*(long long)sb->size<<10)); } printf(" Raid Devices : %d\n", sb->raid_disks); printf(" Total Devices : %d\n", sb->nr_disks); @@ -278,7 +278,7 @@ static void examine_super1(struct supertype *st, char *homehost) (unsigned long long)__le64_to_cpu(sb->data_size), human_size(__le64_to_cpu(sb->data_size)<<9)); if (__le32_to_cpu(sb->level) > 0) { - int ddsks=0; + int ddsks = 0, ddsks_denom = 1; switch(__le32_to_cpu(sb->level)) { case 1: ddsks=1;break; case 4: @@ -286,13 +286,15 @@ static void examine_super1(struct supertype *st, char *homehost) case 6: ddsks = __le32_to_cpu(sb->raid_disks)-2; break; case 10: layout = __le32_to_cpu(sb->layout); - ddsks = __le32_to_cpu(sb->raid_disks) - / (layout&255) / ((layout>>8)&255); + ddsks = __le32_to_cpu(sb->raid_disks); + ddsks_denom = (layout&255) * ((layout>>8)&255); } - if (ddsks) + if (ddsks) { + long long asize = __le64_to_cpu(sb->size); + asize = (asize << 9) * ddsks / ddsks_denom; printf(" Array Size : %llu%s\n", - ddsks*(unsigned long long)__le64_to_cpu(sb->size), - human_size(ddsks*__le64_to_cpu(sb->size)<<9)); + asize >> 10, human_size(asize)); + } if (sb->size != sb->data_size) printf(" Used Dev Size : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->size), |