Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / md / raid0.c
index e7d934e..cb8c631 100644 (file)
@@ -113,21 +113,16 @@ static int create_strip_zones (mddev_t *mddev)
        }
        printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
 
-       conf->strip_zone = kmalloc(sizeof(struct strip_zone)*
+       conf->strip_zone = kzalloc(sizeof(struct strip_zone)*
                                conf->nr_strip_zones, GFP_KERNEL);
        if (!conf->strip_zone)
                return 1;
-       conf->devlist = kmalloc(sizeof(mdk_rdev_t*)*
+       conf->devlist = kzalloc(sizeof(mdk_rdev_t*)*
                                conf->nr_strip_zones*mddev->raid_disks,
                                GFP_KERNEL);
        if (!conf->devlist)
                return 1;
 
-       memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
-                                  conf->nr_strip_zones);
-       memset(conf->devlist, 0,
-              sizeof(mdk_rdev_t*) * conf->nr_strip_zones * mddev->raid_disks);
-
        /* The first zone must contain all devices, so here we check that
         * there is a proper alignment of slots to devices and find them all
         */
@@ -280,7 +275,11 @@ static int raid0_run (mddev_t *mddev)
        mdk_rdev_t *rdev;
        struct list_head *tmp;
 
-       printk("%s: setting max_sectors to %d, segment boundary to %d\n",
+       if (mddev->chunk_size == 0) {
+               printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
+               return -EINVAL;
+       }
+       printk(KERN_INFO "%s: setting max_sectors to %d, segment boundary to %d\n",
               mdname(mddev),
               mddev->chunk_size >> 9,
               (mddev->chunk_size>>1)-1);
@@ -307,23 +306,20 @@ static int raid0_run (mddev_t *mddev)
        printk("raid0 : conf->hash_spacing is %llu blocks.\n",
                (unsigned long long)conf->hash_spacing);
        {
-#if __GNUC__ < 3
-               volatile
-#endif
                sector_t s = mddev->array_size;
                sector_t space = conf->hash_spacing;
                int round;
                conf->preshift = 0;
-               if (sizeof(sector_t) > sizeof(unsigned long)) {
+               if (sizeof(sector_t) > sizeof(u32)) {
                        /*shift down space and s so that sector_div will work */
-                       while (space > (sector_t) (~(unsigned long)0)) {
+                       while (space > (sector_t) (~(u32)0)) {
                                s >>= 1;
                                space >>= 1;
                                s += 1; /* force round-up */
                                conf->preshift++;
                        }
                }
-               round = sector_div(s, (unsigned long)space) ? 1 : 0;
+               round = sector_div(s, (u32)space) ? 1 : 0;
                nb_zone = s + round;
        }
        printk("raid0 : nb_zone is %d.\n", nb_zone);
@@ -335,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;
@@ -361,7 +358,7 @@ static int raid0_run (mddev_t *mddev)
         * chunksize should be used in that case.
         */
        {
-               int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_CACHE_SIZE;
+               int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_SIZE;
                if (mddev->queue->backing_dev_info.ra_pages < 2* stripe)
                        mddev->queue->backing_dev_info.ra_pages = 2* stripe;
        }
@@ -371,14 +368,12 @@ static int raid0_run (mddev_t *mddev)
        return 0;
 
 out_free_conf:
-       if (conf->strip_zone)
-               kfree(conf->strip_zone);
-       if (conf->devlist)
-               kfree (conf->devlist);
+       kfree(conf->strip_zone);
+       kfree(conf->devlist);
        kfree(conf);
        mddev->private = NULL;
 out:
-       return 1;
+       return -ENOMEM;
 }
 
 static int raid0_stop (mddev_t *mddev)
@@ -386,11 +381,11 @@ static int raid0_stop (mddev_t *mddev)
        raid0_conf_t *conf = mddev_to_conf(mddev);
 
        blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
-       kfree (conf->hash_table);
+       kfree(conf->hash_table);
        conf->hash_table = NULL;
-       kfree (conf->strip_zone);
+       kfree(conf->strip_zone);
        conf->strip_zone = NULL;
-       kfree (conf);
+       kfree(conf);
        mddev->private = NULL;
 
        return 0;
@@ -405,15 +400,16 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
        mdk_rdev_t *tmp_dev;
        unsigned long chunk;
        sector_t block, rsect;
+       const int rw = bio_data_dir(bio);
 
-       if (bio_data_dir(bio)==WRITE) {
-               disk_stat_inc(mddev->gendisk, writes);
-               disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
-       } else {
-               disk_stat_inc(mddev->gendisk, reads);
-               disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
+       if (unlikely(bio_barrier(bio))) {
+               bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+               return 0;
        }
 
+       disk_stat_inc(mddev->gendisk, ios[rw]);
+       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+
        chunk_size = mddev->chunk_size >> 10;
        chunk_sects = mddev->chunk_size >> 9;
        chunksize_bits = ffz(~chunk_size);
@@ -441,11 +437,8 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
  
 
        {
-#if __GNUC__ < 3
-               volatile
-#endif
                sector_t x = block >> conf->preshift;
-               sector_div(x, (unsigned long)conf->hash_spacing);
+               sector_div(x, (u32)conf->hash_spacing);
                zone = conf->hash_table[x];
        }
  
@@ -513,9 +506,10 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev)
        return;
 }
 
-static mdk_personality_t raid0_personality=
+static struct mdk_personality raid0_personality=
 {
        .name           = "raid0",
+       .level          = 0,
        .owner          = THIS_MODULE,
        .make_request   = raid0_make_request,
        .run            = raid0_run,
@@ -525,15 +519,17 @@ static mdk_personality_t raid0_personality=
 
 static int __init raid0_init (void)
 {
-       return register_md_personality (RAID0, &raid0_personality);
+       return register_md_personality (&raid0_personality);
 }
 
 static void raid0_exit (void)
 {
-       unregister_md_personality (RAID0);
+       unregister_md_personality (&raid0_personality);
 }
 
 module_init(raid0_init);
 module_exit(raid0_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-2"); /* RAID0 */
+MODULE_ALIAS("md-raid0");
+MODULE_ALIAS("md-level-0");