]> git.neil.brown.name Git - mdadm.git/commitdiff
Examine: fix array size calculation for RAID10.
authorNeilBrown <neilb@suse.de>
Thu, 22 Mar 2012 03:43:09 +0000 (14:43 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 22 Mar 2012 03:43:09 +0000 (14:43 +1100)
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>
super0.c
super1.c

index eca40d28cf79bb3699f248980265f838d7e9f8e3..137579986b176abf827d682b5bf83c79a9eff361 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -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);
index 0a3b6d0ebc819ecd5b736f9510540b10a2c022b0..20f4c866ee9e77309810794d7df6219fc7e2dea5 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -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),