ehea: Whitespace cleanup
[safe/jmp/linux-2.6] / drivers / md / raid10.c
index 7bf5ce2..9eb66c1 100644 (file)
@@ -429,7 +429,7 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev)
                if (dev < 0)
                        dev += conf->raid_disks;
        } else {
-               while (sector > conf->stride) {
+               while (sector >= conf->stride) {
                        sector -= conf->stride;
                        if (dev < conf->near_copies)
                                dev += conf->raid_disks - conf->near_copies;
@@ -648,6 +648,26 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int raid10_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       conf_t *conf = mddev_to_conf(mddev);
+       int i, ret = 0;
+
+       rcu_read_lock();
+       for (i = 0; i < mddev->raid_disks && ret == 0; i++) {
+               mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+               if (rdev && !test_bit(Faulty, &rdev->flags)) {
+                       request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+                       ret |= bdi_congested(&q->backing_dev_info, bits);
+               }
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
+
 /* Barriers....
  * Sometimes we need to suspend IO while we do something else,
  * either some resync/recovery, or reconfigure the array.
@@ -762,6 +782,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
        int i;
        int chunk_sects = conf->chunk_mask + 1;
        const int rw = bio_data_dir(bio);
+       const int do_sync = bio_sync(bio);
        struct bio_list bl;
        unsigned long flags;
 
@@ -843,7 +864,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
                        mirror->rdev->data_offset;
                read_bio->bi_bdev = mirror->rdev->bdev;
                read_bio->bi_end_io = raid10_end_read_request;
-               read_bio->bi_rw = READ;
+               read_bio->bi_rw = READ | do_sync;
                read_bio->bi_private = r10_bio;
 
                generic_make_request(read_bio);
@@ -889,7 +910,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
                        conf->mirrors[d].rdev->data_offset;
                mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
                mbio->bi_end_io = raid10_end_write_request;
-               mbio->bi_rw = WRITE;
+               mbio->bi_rw = WRITE | do_sync;
                mbio->bi_private = r10_bio;
 
                atomic_inc(&r10_bio->remaining);
@@ -902,6 +923,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
        blk_plug_device(mddev->queue);
        spin_unlock_irqrestore(&conf->device_lock, flags);
 
+       if (do_sync)
+               md_wakeup_thread(mddev->thread);
+
        return 0;
 }
 
@@ -921,7 +945,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
                        seq_printf(seq, " %d far-copies", conf->far_copies);
        }
        seq_printf(seq, " [%d/%d] [", conf->raid_disks,
-                                               conf->working_disks);
+                                       conf->raid_disks - mddev->degraded);
        for (i = 0; i < conf->raid_disks; i++)
                seq_printf(seq, "%s",
                              conf->mirrors[i].rdev &&
@@ -941,7 +965,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
         * else mark the drive as failed
         */
        if (test_bit(In_sync, &rdev->flags)
-           && conf->working_disks == 1)
+           && conf->raid_disks-mddev->degraded == 1)
                /*
                 * Don't fail the drive, just return an IO error.
                 * The test should really be more sophisticated than
@@ -950,20 +974,21 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                 * really dead" tests...
                 */
                return;
-       if (test_bit(In_sync, &rdev->flags)) {
+       if (test_and_clear_bit(In_sync, &rdev->flags)) {
+               unsigned long flags;
+               spin_lock_irqsave(&conf->device_lock, flags);
                mddev->degraded++;
-               conf->working_disks--;
+               spin_unlock_irqrestore(&conf->device_lock, flags);
                /*
                 * if recovery is running, make sure it aborts.
                 */
                set_bit(MD_RECOVERY_ERR, &mddev->recovery);
        }
-       clear_bit(In_sync, &rdev->flags);
        set_bit(Faulty, &rdev->flags);
-       mddev->sb_dirty = 1;
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
        printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
                "       Operation continuing on %d devices\n",
-               bdevname(rdev->bdev,b), conf->working_disks);
+               bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 }
 
 static void print_conf(conf_t *conf)
@@ -976,7 +1001,7 @@ static void print_conf(conf_t *conf)
                printk("(!conf)\n");
                return;
        }
-       printk(" --- wd:%d rd:%d\n", conf->working_disks,
+       printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
                conf->raid_disks);
 
        for (i = 0; i < conf->raid_disks; i++) {
@@ -1034,10 +1059,11 @@ static int raid10_spare_active(mddev_t *mddev)
                tmp = conf->mirrors + i;
                if (tmp->rdev
                    && !test_bit(Faulty, &tmp->rdev->flags)
-                   && !test_bit(In_sync, &tmp->rdev->flags)) {
-                       conf->working_disks++;
+                   && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        mddev->degraded--;
-                       set_bit(In_sync, &tmp->rdev->flags);
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                }
        }
 
@@ -1448,8 +1474,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
                                               "raid10:%s: read error corrected"
                                               " (%d sectors at %llu on %s)\n",
                                               mdname(mddev), s,
-                                              (unsigned long long)sect+
-                                                   rdev->data_offset,
+                                              (unsigned long long)(sect+
+                                                   rdev->data_offset),
                                               bdevname(rdev->bdev, b));
 
                                rdev_dec_pending(rdev, mddev);
@@ -1541,6 +1567,7 @@ static void raid10d(mddev_t *mddev)
                                       (unsigned long long)r10_bio->sector);
                                raid_end_bio_io(r10_bio);
                        } else {
+                               const int do_sync = bio_sync(r10_bio->master_bio);
                                rdev = conf->mirrors[mirror].rdev;
                                if (printk_ratelimit())
                                        printk(KERN_ERR "raid10: %s: redirecting sector %llu to"
@@ -1552,7 +1579,7 @@ static void raid10d(mddev_t *mddev)
                                bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr
                                        + rdev->data_offset;
                                bio->bi_bdev = rdev->bdev;
-                               bio->bi_rw = READ;
+                               bio->bi_rw = READ | do_sync;
                                bio->bi_private = r10_bio;
                                bio->bi_end_io = raid10_end_read_request;
                                unplug = 1;
@@ -1763,7 +1790,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                                biolist = bio;
                                                bio->bi_private = r10_bio;
                                                bio->bi_end_io = end_sync_read;
-                                               bio->bi_rw = 0;
+                                               bio->bi_rw = READ;
                                                bio->bi_sector = r10_bio->devs[j].addr +
                                                        conf->mirrors[d].rdev->data_offset;
                                                bio->bi_bdev = conf->mirrors[d].rdev->bdev;
@@ -1774,12 +1801,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                                for (k=0; k<conf->copies; k++)
                                                        if (r10_bio->devs[k].devnum == i)
                                                                break;
+                                               BUG_ON(k == conf->copies);
                                                bio = r10_bio->devs[1].bio;
                                                bio->bi_next = biolist;
                                                biolist = bio;
                                                bio->bi_private = r10_bio;
                                                bio->bi_end_io = end_sync_write;
-                                               bio->bi_rw = 1;
+                                               bio->bi_rw = WRITE;
                                                bio->bi_sector = r10_bio->devs[k].addr +
                                                        conf->mirrors[i].rdev->data_offset;
                                                bio->bi_bdev = conf->mirrors[i].rdev->bdev;
@@ -1839,6 +1867,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                        int d = r10_bio->devs[i].devnum;
                        bio = r10_bio->devs[i].bio;
                        bio->bi_end_io = NULL;
+                       clear_bit(BIO_UPTODATE, &bio->bi_flags);
                        if (conf->mirrors[d].rdev == NULL ||
                            test_bit(Faulty, &conf->mirrors[d].rdev->flags))
                                continue;
@@ -1848,7 +1877,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                        biolist = bio;
                        bio->bi_private = r10_bio;
                        bio->bi_end_io = end_sync_read;
-                       bio->bi_rw = 0;
+                       bio->bi_rw = READ;
                        bio->bi_sector = r10_bio->devs[i].addr +
                                conf->mirrors[d].rdev->data_offset;
                        bio->bi_bdev = conf->mirrors[d].rdev->bdev;
@@ -1994,19 +2023,35 @@ static int run(mddev_t *mddev)
        if (!conf->tmppage)
                goto out_free_conf;
 
+       conf->mddev = mddev;
+       conf->raid_disks = mddev->raid_disks;
        conf->near_copies = nc;
        conf->far_copies = fc;
        conf->copies = nc*fc;
        conf->far_offset = fo;
        conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
        conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
+       size = mddev->size >> (conf->chunk_shift-1);
+       sector_div(size, fc);
+       size = size * conf->raid_disks;
+       sector_div(size, nc);
+       /* 'size' is now the number of chunks in the array */
+       /* calculate "used chunks per device" in 'stride' */
+       stride = size * conf->copies;
+
+       /* We need to round up when dividing by raid_disks to
+        * get the stride size.
+        */
+       stride += conf->raid_disks - 1;
+       sector_div(stride, conf->raid_disks);
+       mddev->size = stride  << (conf->chunk_shift-1);
+
        if (fo)
-               conf->stride = 1 << conf->chunk_shift;
-       else {
-               stride = mddev->size >> (conf->chunk_shift-1);
+               stride = 1;
+       else
                sector_div(stride, fc);
-               conf->stride = stride << conf->chunk_shift;
-       }
+       conf->stride = stride << conf->chunk_shift;
+
        conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
                                                r10bio_pool_free, conf);
        if (!conf->r10bio_pool) {
@@ -2035,11 +2080,7 @@ static int run(mddev_t *mddev)
                        mddev->queue->max_sectors = (PAGE_SIZE>>9);
 
                disk->head_position = 0;
-               if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
-                       conf->working_disks++;
        }
-       conf->raid_disks = mddev->raid_disks;
-       conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        INIT_LIST_HEAD(&conf->retry_list);
 
@@ -2059,7 +2100,7 @@ static int run(mddev_t *mddev)
                disk = conf->mirrors + i;
 
                if (!disk->rdev ||
-                   !test_bit(In_sync, &rdev->flags)) {
+                   !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
                }
@@ -2081,19 +2122,13 @@ static int run(mddev_t *mddev)
        /*
         * Ok, everything is just fine now
         */
-       if (conf->far_offset) {
-               size = mddev->size >> (conf->chunk_shift-1);
-               size *= conf->raid_disks;
-               size <<= conf->chunk_shift;
-               sector_div(size, conf->far_copies);
-       } else
-               size = conf->stride * conf->raid_disks;
-       sector_div(size, conf->near_copies);
-       mddev->array_size = size/2;
-       mddev->resync_max_sectors = size;
+       mddev->array_size = size << (conf->chunk_shift-1);
+       mddev->resync_max_sectors = size << conf->chunk_shift;
 
        mddev->queue->unplug_fn = raid10_unplug;
        mddev->queue->issue_flush_fn = raid10_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = raid10_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
 
        /* Calculate max read-ahead size.
         * We need to readahead at least twice a whole stripe....