diff options
author | NeilBrown <neilb@suse.de> | 2013-11-14 15:16:15 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-11-14 15:16:15 +1100 |
commit | ba8805b97320416e7c5bb8f55d2bd06d5c319e7d (patch) | |
tree | 18f2235f3a8992a702f5d75e8c9f608076b01952 /drivers/md/raid5.c | |
parent | 02e5f5c0a0f726e66e3d8506ea1691e344277969 (diff) | |
download | talos-op-linux-ba8805b97320416e7c5bb8f55d2bd06d5c319e7d.tar.gz talos-op-linux-ba8805b97320416e7c5bb8f55d2bd06d5c319e7d.zip |
md/raid5.c: add proper locking to error path of raid5_start_reshape.
If raid5_start_reshape errors out, we need to reset all the fields
that were updated (not just some), and need to use the seq_counter
to ensure make_request() doesn't use an inconsitent state.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f013d3662665..4bbcb7e26d12 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6384,12 +6384,18 @@ static int raid5_start_reshape(struct mddev *mddev) if (!mddev->sync_thread) { mddev->recovery = 0; spin_lock_irq(&conf->device_lock); + write_seqcount_begin(&conf->gen_lock); mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks; + mddev->new_chunk_sectors = + conf->chunk_sectors = conf->prev_chunk_sectors; + mddev->new_layout = conf->algorithm = conf->prev_algo; rdev_for_each(rdev, mddev) rdev->new_data_offset = rdev->data_offset; smp_wmb(); + conf->generation --; conf->reshape_progress = MaxSector; mddev->reshape_position = MaxSector; + write_seqcount_end(&conf->gen_lock); spin_unlock_irq(&conf->device_lock); return -EAGAIN; } |