if (r1_bio->bios[mirror] == bio)
break;
- if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
+ if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
set_bit(R1BIO_BarrierRetry, &r1_bio->state);
r1_bio->mddev->barriers_work = 0;
- /* Don't rdev_dec_pending in this branch - keep it for the retry */
} else {
/*
* this branch is our 'one mirror IO has finished' event handler:
}
}
}
- rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
}
/*
*
if (atomic_dec_and_test(&r1_bio->remaining)) {
if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
reschedule_retry(r1_bio);
+ /* Don't dec_pending yet, we want to hold
+ * the reference over the retry
+ */
goto out;
}
- /* it really is the end of this request */
if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
/* free extra copy of the data pages */
int i = bio->bi_vcnt;
md_write_end(r1_bio->mddev);
raid_end_bio_io(r1_bio);
}
+
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
out:
if (to_put)
bio_put(to_put);
const int rw = bio_data_dir(bio);
int do_barriers;
+ if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
/*
* Register the new request and wait if the reconstruction
* thread has put up a bar for new requests.
* Continue immediately if no resync is active currently.
- * We test barriers_work *after* md_write_start as md_write_start
- * may cause the first superblock write, and that will check out
- * if barriers work.
*/
-
md_write_start(mddev, bio); /* wait on superblock update early */
- if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
- if (rw == WRITE)
- md_write_end(mddev);
- bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
- return 0;
- }
-
wait_barrier(conf);
disk_stat_inc(mddev->gendisk, ios[rw]);
mirror = i;
break;
}
- if (!uptodate) {
- int sync_blocks = 0;
- sector_t s = r1_bio->sector;
- long sectors_to_go = r1_bio->sectors;
- /* make sure these bits doesn't get cleared. */
- do {
- bitmap_end_sync(mddev->bitmap, r1_bio->sector,
- &sync_blocks, 1);
- s += sync_blocks;
- sectors_to_go -= sync_blocks;
- } while (sectors_to_go > 0);
+ if (!uptodate)
md_error(mddev, conf->mirrors[mirror].rdev);
- }
update_head_pos(mirror, r1_bio);
unplug = 1;
} else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
/* some requests in the r1bio were BIO_RW_BARRIER
- * requests which failed with -EOPNOTSUPP. Hohumm..
+ * requests which failed with -ENOTSUPP. Hohumm..
* Better resubmit without the barrier.
* We know which devices to resubmit for, because
* all others have had their bios[] entry cleared.
- * We already have a nr_pending reference on these rdevs.
*/
int i;
clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
clear_bit(R1BIO_Barrier, &r1_bio->state);
- for (i=0; i < conf->raid_disks; i++)
- if (r1_bio->bios[i])
- atomic_inc(&r1_bio->remaining);
for (i=0; i < conf->raid_disks; i++)
if (r1_bio->bios[i]) {
struct bio_vec *bvec;
int buffs;
buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
- BUG_ON(conf->r1buf_pool);
+ if (conf->r1buf_pool)
+ BUG();
conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free,
conf->poolinfo);
if (!conf->r1buf_pool)
!conf->fullsync &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
break;
- BUG_ON(sync_blocks < (PAGE_SIZE>>9));
+ if (sync_blocks < (PAGE_SIZE>>9))
+ BUG();
if (len > (sync_blocks<<9))
len = sync_blocks<<9;
}
mdname(mddev), mddev->level);
goto out;
}
- if (mddev->reshape_position != MaxSector) {
- printk("raid1: %s: reshape_position set but not supported\n",
- mdname(mddev));
- goto out;
- }
/*
* copy the already verified devices into our private RAID1
* bookkeeping area. [whatever we allocate in run(),
return 0;
}
-static int raid1_reshape(mddev_t *mddev)
+static int raid1_reshape(mddev_t *mddev, int raid_disks)
{
/* We need to:
* 1/ resize the r1bio_pool
struct pool_info *newpoolinfo;
mirror_info_t *newmirrors;
conf_t *conf = mddev_to_conf(mddev);
- int cnt, raid_disks;
+ int cnt;
int d, d2;
- /* Cannot change chunk_size, layout, or level */
- if (mddev->chunk_size != mddev->new_chunk ||
- mddev->layout != mddev->new_layout ||
- mddev->level != mddev->new_level) {
- mddev->new_chunk = mddev->chunk_size;
- mddev->new_layout = mddev->layout;
- mddev->new_level = mddev->level;
- return -EINVAL;
- }
-
- raid_disks = mddev->raid_disks + mddev->delta_disks;
-
if (raid_disks < conf->raid_disks) {
cnt=0;
for (d= 0; d < conf->raid_disks; d++)
mddev->degraded += (raid_disks - conf->raid_disks);
conf->raid_disks = mddev->raid_disks = raid_disks;
- mddev->delta_disks = 0;
conf->last_used = 0; /* just make sure it is in-range */
lower_barrier(conf);
.spare_active = raid1_spare_active,
.sync_request = sync_request,
.resize = raid1_resize,
- .check_reshape = raid1_reshape,
+ .reshape = raid1_reshape,
.quiesce = raid1_quiesce,
};