[PATCH] md: fix possible oops when starting a raid0 array
authorNeilBrown <neilb@suse.de>
Tue, 23 May 2006 05:35:26 +0000 (22:35 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 23 May 2006 17:35:31 +0000 (10:35 -0700)
This loop that sets up the hash_table has problems.

Careful examination will show that the last time through, everything but
the first line is pointless.  This is because all it does is change 'cur'
and 'size' and neither of these are used after the loop.  This should ring
warning bells...  That last time through the loop,

        size += conf->strip_zone[cur].size

can index off the end of the strip_zone array.  Depending on what it finds
there, it might exit the loop cleanly, or it might spin going further and
further beyond the array until it hits an unmapped address.

This patch rearranges the code so that the last, pointless, iteration of
the loop never happens.  i.e.  the one statement of the last loop that is
needed is moved the the end of the previous loop - or to before the loop
starts - and the loop counter starts from 1 instead of 0.

Cc: "Don Dupuis" <dondster@gmail.com>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/md/raid0.c

index 678f4dbbea1d5c22082d13fb1afd321465b61f28..cb8c6317e4e5fc367c7098a87e310b5ed059f724 100644 (file)
@@ -331,13 +331,14 @@ static int raid0_run (mddev_t *mddev)
                goto out_free_conf;
        size = conf->strip_zone[cur].size;
 
-       for (i=0; i< nb_zone; i++) {
-               conf->hash_table[i] = conf->strip_zone + cur;
+       conf->hash_table[0] = conf->strip_zone + cur;
+       for (i=1; i< nb_zone; i++) {
                while (size <= conf->hash_spacing) {
                        cur++;
                        size += conf->strip_zone[cur].size;
                }
                size -= conf->hash_spacing;
+               conf->hash_table[i] = conf->strip_zone + cur;
        }
        if (conf->preshift) {
                conf->hash_spacing >>= conf->preshift;