dm: add dm_deleting_md function
[safe/jmp/linux-2.6] / drivers / md / raid10.c
index ad153b2..c2cb7b8 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
 #include "md.h"
-#include "dm-bio-list.h"
 #include "raid10.h"
 #include "bitmap.h"
 
@@ -69,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
 
        /* allocate a r10bio with room for raid_disks entries in the bios array */
        r10_bio = kzalloc(size, gfp_flags);
-       if (!r10_bio)
+       if (!r10_bio && conf->mddev)
                unplug_slaves(conf->mddev);
 
        return r10_bio;
@@ -189,7 +188,7 @@ static void put_all_bios(conf_t *conf, r10bio_t *r10_bio)
 
 static void free_r10bio(r10bio_t *r10_bio)
 {
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
 
        /*
         * Wake up any possible resync thread that waits for the device
@@ -203,7 +202,7 @@ static void free_r10bio(r10bio_t *r10_bio)
 
 static void put_buf(r10bio_t *r10_bio)
 {
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
 
        mempool_free(r10_bio, conf->r10buf_pool);
 
@@ -214,7 +213,7 @@ static void reschedule_retry(r10bio_t *r10_bio)
 {
        unsigned long flags;
        mddev_t *mddev = r10_bio->mddev;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
 
        spin_lock_irqsave(&conf->device_lock, flags);
        list_add(&r10_bio->retry_list, &conf->retry_list);
@@ -246,7 +245,7 @@ static void raid_end_bio_io(r10bio_t *r10_bio)
  */
 static inline void update_head_pos(int slot, r10bio_t *r10_bio)
 {
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
 
        conf->mirrors[r10_bio->devs[slot].devnum].head_position =
                r10_bio->devs[slot].addr + (r10_bio->sectors);
@@ -257,7 +256,7 @@ static void raid10_end_read_request(struct bio *bio, int error)
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private);
        int slot, dev;
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
 
 
        slot = r10_bio->read_slot;
@@ -298,7 +297,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private);
        int slot, dev;
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
 
        for (slot = 0; slot < conf->copies; slot++)
                if (r10_bio->devs[slot].bio == bio)
@@ -462,7 +461,7 @@ static int raid10_mergeable_bvec(struct request_queue *q,
        mddev_t *mddev = q->queuedata;
        sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
        int max;
-       unsigned int chunk_sectors = mddev->chunk_size >> 9;
+       unsigned int chunk_sectors = mddev->chunk_sectors;
        unsigned int bio_sectors = bvm->bi_size >> 9;
 
        max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
@@ -597,7 +596,7 @@ rb_out:
 
 static void unplug_slaves(mddev_t *mddev)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i;
 
        rcu_read_lock();
@@ -629,9 +628,11 @@ static void raid10_unplug(struct request_queue *q)
 static int raid10_congested(void *data, int bits)
 {
        mddev_t *mddev = data;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i, ret = 0;
 
+       if (mddev_congested(mddev, bits))
+               return 1;
        rcu_read_lock();
        for (i = 0; i < mddev->raid_disks && ret == 0; i++) {
                mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
@@ -789,7 +790,7 @@ static void unfreeze_array(conf_t *conf)
 static int make_request(struct request_queue *q, struct bio * bio)
 {
        mddev_t *mddev = q->queuedata;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        mirror_info_t *mirror;
        r10bio_t *r10_bio;
        struct bio *read_bio;
@@ -797,12 +798,12 @@ static int make_request(struct request_queue *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);
+       const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO);
        struct bio_list bl;
        unsigned long flags;
        mdk_rdev_t *blocked_rdev;
 
-       if (unlikely(bio_barrier(bio))) {
+       if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
                bio_endio(bio, -EOPNOTSUPP);
                return 0;
        }
@@ -883,7 +884,7 @@ static int make_request(struct request_queue *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 | do_sync;
+               read_bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO);
                read_bio->bi_private = r10_bio;
 
                generic_make_request(read_bio);
@@ -951,7 +952,7 @@ static int make_request(struct request_queue *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 | do_sync;
+               mbio->bi_rw = WRITE | (do_sync << BIO_RW_SYNCIO);
                mbio->bi_private = r10_bio;
 
                atomic_inc(&r10_bio->remaining);
@@ -982,11 +983,11 @@ static int make_request(struct request_queue *q, struct bio * bio)
 
 static void status(struct seq_file *seq, mddev_t *mddev)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i;
 
        if (conf->near_copies < conf->raid_disks)
-               seq_printf(seq, " %dK chunks", mddev->chunk_size/1024);
+               seq_printf(seq, " %dK chunks", mddev->chunk_sectors / 2);
        if (conf->near_copies > 1)
                seq_printf(seq, " %d near-copies", conf->near_copies);
        if (conf->far_copies > 1) {
@@ -1007,7 +1008,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        char b[BDEVNAME_SIZE];
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
 
        /*
         * If it is not operational, then we have already marked it as dead
@@ -1152,15 +1153,15 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        for ( ; mirror <= last ; mirror++)
                if ( !(p=conf->mirrors+mirror)->rdev) {
 
-                       blk_queue_stack_limits(mddev->queue,
-                                              rdev->bdev->bd_disk->queue);
+                       disk_stack_limits(mddev->gendisk, rdev->bdev,
+                                         rdev->data_offset << 9);
                        /* as we don't honour merge_bvec_fn, we must never risk
                         * violating it, so limit ->max_sector to one PAGE, as
                         * a one page request is never in violation.
                         */
                        if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                           mddev->queue->max_sectors > (PAGE_SIZE>>9))
-                               mddev->queue->max_sectors = (PAGE_SIZE>>9);
+                           queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
+                               blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
@@ -1171,6 +1172,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                        break;
                }
 
+       md_integrity_add_rdev(rdev, mddev);
        print_conf(conf);
        return err;
 }
@@ -1204,7 +1206,9 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
                        /* lost the race, try later */
                        err = -EBUSY;
                        p->rdev = rdev;
+                       goto abort;
                }
+               md_integrity_register(mddev);
        }
 abort:
 
@@ -1216,7 +1220,7 @@ abort:
 static void end_sync_read(struct bio *bio, int error)
 {
        r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private);
-       conf_t *conf = mddev_to_conf(r10_bio->mddev);
+       conf_t *conf = r10_bio->mddev->private;
        int i,d;
 
        for (i=0; i<conf->copies; i++)
@@ -1254,7 +1258,7 @@ static void end_sync_write(struct bio *bio, int error)
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private);
        mddev_t *mddev = r10_bio->mddev;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i,d;
 
        for (i = 0; i < conf->copies; i++)
@@ -1301,7 +1305,7 @@ static void end_sync_write(struct bio *bio, int error)
  */
 static void sync_request_write(mddev_t *mddev, r10bio_t *r10_bio)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i, first;
        struct bio *tbio, *fbio;
 
@@ -1401,7 +1405,7 @@ done:
 
 static void recovery_request_write(mddev_t *mddev, r10bio_t *r10_bio)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        int i, d;
        struct bio *bio, *wbio;
 
@@ -1550,7 +1554,7 @@ static void raid10d(mddev_t *mddev)
        r10bio_t *r10_bio;
        struct bio *bio;
        unsigned long flags;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        struct list_head *head = &conf->retry_list;
        int unplug=0;
        mdk_rdev_t *rdev;
@@ -1573,7 +1577,7 @@ static void raid10d(mddev_t *mddev)
                spin_unlock_irqrestore(&conf->device_lock, flags);
 
                mddev = r10_bio->mddev;
-               conf = mddev_to_conf(mddev);
+               conf = mddev->private;
                if (test_bit(R10BIO_IsSync, &r10_bio->state)) {
                        sync_request_write(mddev, r10_bio);
                        unplug = 1;
@@ -1608,7 +1612,7 @@ static void raid10d(mddev_t *mddev)
                                raid_end_bio_io(r10_bio);
                                bio_put(bio);
                        } else {
-                               const int do_sync = bio_sync(r10_bio->master_bio);
+                               const bool do_sync = bio_rw_flagged(r10_bio->master_bio, BIO_RW_SYNCIO);
                                bio_put(bio);
                                rdev = conf->mirrors[mirror].rdev;
                                if (printk_ratelimit())
@@ -1621,13 +1625,14 @@ 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 | do_sync;
+                               bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO);
                                bio->bi_private = r10_bio;
                                bio->bi_end_io = raid10_end_read_request;
                                unplug = 1;
                                generic_make_request(bio);
                        }
                }
+               cond_resched();
        }
        if (unplug)
                unplug_slaves(mddev);
@@ -1681,7 +1686,7 @@ static int init_resync(conf_t *conf)
 
 static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
        r10bio_t *r10_bio;
        struct bio *biolist = NULL, *bio;
        sector_t max_sector, nr_sectors;
@@ -1771,7 +1776,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        max_sync = RESYNC_PAGES << (PAGE_SHIFT-9);
        if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
                /* recovery... the complicated one */
-               int i, j, k;
+               int j, k;
                r10_bio = NULL;
 
                for (i=0 ; i<conf->raid_disks; i++)
@@ -1810,17 +1815,17 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                r10_bio->sector = sect;
 
                                raid10_find_phys(conf, r10_bio);
-                               /* Need to check if this section will still be
+
+                               /* Need to check if the array will still be
                                 * degraded
                                 */
-                               for (j=0; j<conf->copies;j++) {
-                                       int d = r10_bio->devs[j].devnum;
-                                       if (conf->mirrors[d].rdev == NULL ||
-                                           test_bit(Faulty, &conf->mirrors[d].rdev->flags)) {
+                               for (j=0; j<conf->raid_disks; j++)
+                                       if (conf->mirrors[j].rdev == NULL ||
+                                           test_bit(Faulty, &conf->mirrors[j].rdev->flags)) {
                                                still_degraded = 1;
                                                break;
                                        }
-                               }
+
                                must_sync = bitmap_start_sync(mddev->bitmap, sect,
                                                              &sync_blocks, still_degraded);
 
@@ -2027,7 +2032,7 @@ static sector_t
 raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
 {
        sector_t size;
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
 
        if (!raid_disks)
                raid_disks = mddev->raid_disks;
@@ -2045,15 +2050,16 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
 static int run(mddev_t *mddev)
 {
        conf_t *conf;
-       int i, disk_idx;
+       int i, disk_idx, chunk_size;
        mirror_info_t *disk;
        mdk_rdev_t *rdev;
        int nc, fc, fo;
        sector_t stride, size;
 
-       if (mddev->chunk_size < PAGE_SIZE) {
+       if (mddev->chunk_sectors < (PAGE_SIZE >> 9) ||
+           !is_power_of_2(mddev->chunk_sectors)) {
                printk(KERN_ERR "md/raid10: chunk size must be "
-                      "at least PAGE_SIZE(%ld).\n", PAGE_SIZE);
+                      "at least PAGE_SIZE(%ld) and be a power of 2.\n", PAGE_SIZE);
                return -EINVAL;
        }
 
@@ -2090,14 +2096,13 @@ 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;
+       conf->chunk_mask = mddev->chunk_sectors - 1;
+       conf->chunk_shift = ffz(~mddev->chunk_sectors);
        size = mddev->dev_sectors >> conf->chunk_shift;
        sector_div(size, fc);
        size = size * conf->raid_disks;
@@ -2127,9 +2132,18 @@ static int run(mddev_t *mddev)
                goto out_free_conf;
        }
 
+       conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        mddev->queue->queue_lock = &conf->device_lock;
 
+       chunk_size = mddev->chunk_sectors << 9;
+       blk_queue_io_min(mddev->queue, chunk_size);
+       if (conf->raid_disks % conf->near_copies)
+               blk_queue_io_opt(mddev->queue, chunk_size * conf->raid_disks);
+       else
+               blk_queue_io_opt(mddev->queue, chunk_size *
+                                (conf->raid_disks / conf->near_copies));
+
        list_for_each_entry(rdev, &mddev->disks, same_set) {
                disk_idx = rdev->raid_disk;
                if (disk_idx >= mddev->raid_disks
@@ -2138,16 +2152,15 @@ static int run(mddev_t *mddev)
                disk = conf->mirrors + disk_idx;
 
                disk->rdev = rdev;
-
-               blk_queue_stack_limits(mddev->queue,
-                                      rdev->bdev->bd_disk->queue);
+               disk_stack_limits(mddev->gendisk, rdev->bdev,
+                                 rdev->data_offset << 9);
                /* as we don't honour merge_bvec_fn, we must never risk
                 * violating it, so limit ->max_sector to one PAGE, as
                 * a one page request is never in violation.
                 */
                if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                   mddev->queue->max_sectors > (PAGE_SIZE>>9))
-                       mddev->queue->max_sectors = (PAGE_SIZE>>9);
+                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
+                       blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
                disk->head_position = 0;
        }
@@ -2178,7 +2191,7 @@ static int run(mddev_t *mddev)
        }
 
 
-       mddev->thread = md_register_thread(raid10d, mddev, "%s_raid10");
+       mddev->thread = md_register_thread(raid10d, mddev, NULL);
        if (!mddev->thread) {
                printk(KERN_ERR
                       "raid10: couldn't allocate thread for %s\n",
@@ -2186,6 +2199,10 @@ static int run(mddev_t *mddev)
                goto out_free_conf;
        }
 
+       if (mddev->recovery_cp != MaxSector)
+               printk(KERN_NOTICE "raid10: %s is not clean"
+                      " -- starting background reconstruction\n",
+                      mdname(mddev));
        printk(KERN_INFO
                "raid10: raid set %s active with %d out of %d devices\n",
                mdname(mddev), mddev->raid_disks - mddev->degraded,
@@ -2194,7 +2211,7 @@ static int run(mddev_t *mddev)
         * Ok, everything is just fine now
         */
        md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
-       mddev->resync_max_sectors = mddev->array_sectors;
+       mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
 
        mddev->queue->unplug_fn = raid10_unplug;
        mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2205,7 +2222,8 @@ static int run(mddev_t *mddev)
         * maybe...
         */
        {
-               int stripe = conf->raid_disks * (mddev->chunk_size / PAGE_SIZE);
+               int stripe = conf->raid_disks *
+                       ((mddev->chunk_sectors << 9) / PAGE_SIZE);
                stripe /= conf->near_copies;
                if (mddev->queue->backing_dev_info.ra_pages < 2* stripe)
                        mddev->queue->backing_dev_info.ra_pages = 2* stripe;
@@ -2213,6 +2231,7 @@ static int run(mddev_t *mddev)
 
        if (conf->near_copies < mddev->raid_disks)
                blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec);
+       md_integrity_register(mddev);
        return 0;
 
 out_free_conf:
@@ -2228,7 +2247,7 @@ out:
 
 static int stop(mddev_t *mddev)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
 
        raise_barrier(conf, 0);
        lower_barrier(conf);
@@ -2246,7 +2265,7 @@ static int stop(mddev_t *mddev)
 
 static void raid10_quiesce(mddev_t *mddev, int state)
 {
-       conf_t *conf = mddev_to_conf(mddev);
+       conf_t *conf = mddev->private;
 
        switch(state) {
        case 1: