]> err.no Git - linux-2.6/blobdiff - drivers/md/raid10.c
Merge branch 'bkl-removal' into next
[linux-2.6] / drivers / md / raid10.c
index 8536ede1e7129c37fc30303e15577c383e68569c..22bb2b1b886d96887948f25fd8efbc199b3b3079 100644 (file)
@@ -439,26 +439,27 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev)
 /**
  *     raid10_mergeable_bvec -- tell bio layer if a two requests can be merged
  *     @q: request queue
- *     @bio: the buffer head that's been built up so far
+ *     @bvm: properties of new bio
  *     @biovec: the request that could be merged to it.
  *
  *     Return amount of bytes we can accept at this offset
  *      If near_copies == raid_disk, there are no striping issues,
  *      but in that case, the function isn't called at all.
  */
-static int raid10_mergeable_bvec(struct request_queue *q, struct bio *bio,
-                               struct bio_vec *bio_vec)
+static int raid10_mergeable_bvec(struct request_queue *q,
+                                struct bvec_merge_data *bvm,
+                                struct bio_vec *biovec)
 {
        mddev_t *mddev = q->queuedata;
-       sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev);
+       sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
        int max;
        unsigned int chunk_sectors = mddev->chunk_size >> 9;
-       unsigned int bio_sectors = bio->bi_size >> 9;
+       unsigned int bio_sectors = bvm->bi_size >> 9;
 
        max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
        if (max < 0) max = 0; /* bio_add cannot handle a negative return */
-       if (max <= bio_vec->bv_len && bio_sectors == 0)
-               return bio_vec->bv_len;
+       if (max <= biovec->bv_len && bio_sectors == 0)
+               return biovec->bv_len;
        else
                return max;
 }
@@ -1020,7 +1021,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                /*
                 * if recovery is running, make sure it aborts.
                 */
-               set_bit(MD_RECOVERY_ERR, &mddev->recovery);
+               set_bit(MD_RECOVERY_INTR, &mddev->recovery);
        }
        set_bit(Faulty, &rdev->flags);
        set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -1171,6 +1172,14 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
                        err = -EBUSY;
                        goto abort;
                }
+               /* Only remove faulty devices in recovery
+                * is not possible.
+                */
+               if (!test_bit(Faulty, &rdev->flags) &&
+                   enough(conf)) {
+                       err = -EBUSY;
+                       goto abort;
+               }
                p->rdev = NULL;
                synchronize_rcu();
                if (atomic_read(&rdev->nr_pending)) {
@@ -1237,6 +1246,7 @@ static void end_sync_write(struct bio *bio, int error)
 
        if (!uptodate)
                md_error(mddev, conf->mirrors[d].rdev);
+
        update_head_pos(i, r10_bio);
 
        while (atomic_dec_and_test(&r10_bio->remaining)) {
@@ -1844,7 +1854,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                        if (rb2)
                                                atomic_dec(&rb2->remaining);
                                        r10_bio = rb2;
-                                       if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery))
+                                       if (!test_and_set_bit(MD_RECOVERY_INTR,
+                                                             &mddev->recovery))
                                                printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n",
                                                       mdname(mddev));
                                        break;
@@ -2127,6 +2138,8 @@ static int run(mddev_t *mddev)
                    !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
+                       if (disk->rdev)
+                               conf->fullsync = 1;
                }
        }