summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-17 09:44:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-17 09:44:35 -0700
commit36a1987cd891fa82d9981886c3abbbe82c428c0d (patch)
tree26f2c1ebc2d0485de222f13ebf812456ee8a7cb8
parent31ae98359d26ff89b745c4f8094093cbf6ccbdc6 (diff)
parent0d9f4f135eb6dea06bdcb7065b1e4ff78274a5e9 (diff)
Merge tag 'md-3.4-fixes' of git://neil.brown.name/md
Pull two md fixes from NeilBrown: "One fixes a bug in the new raid10 resize code so is relevant to 3.4 only. The other fixes a bug in the use of md by dm-raid, so is relevant to any kernel with dm-raid support" * tag 'md-3.4-fixes' of git://neil.brown.name/md: MD: Add del_timer_sync to mddev_suspend (fix nasty panic) md/raid10: set dev_sectors properly when resizing devices in array.
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/raid10.c56
2 files changed, 34 insertions, 24 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 477eb2e180c..01233d855eb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -391,6 +391,8 @@ void mddev_suspend(struct mddev *mddev)
synchronize_rcu();
wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
mddev->pers->quiesce(mddev, 1);
+
+ del_timer_sync(&mddev->safemode_timer);
}
EXPORT_SYMBOL_GPL(mddev_suspend);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c8dbb84d535..3e7b1548111 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3164,12 +3164,40 @@ raid10_size(struct mddev *mddev, sector_t sectors, int raid_disks)
return size << conf->chunk_shift;
}
+static void calc_sectors(struct r10conf *conf, sector_t size)
+{
+ /* Calculate the number of sectors-per-device that will
+ * actually be used, and set conf->dev_sectors and
+ * conf->stride
+ */
+
+ size = size >> conf->chunk_shift;
+ sector_div(size, conf->far_copies);
+ size = size * conf->raid_disks;
+ sector_div(size, conf->near_copies);
+ /* 'size' is now the number of chunks in the array */
+ /* calculate "used chunks per device" */
+ size = size * conf->copies;
+
+ /* We need to round up when dividing by raid_disks to
+ * get the stride size.
+ */
+ size = DIV_ROUND_UP_SECTOR_T(size, conf->raid_disks);
+
+ conf->dev_sectors = size << conf->chunk_shift;
+
+ if (conf->far_offset)
+ conf->stride = 1 << conf->chunk_shift;
+ else {
+ sector_div(size, conf->near_copies);
+ conf->stride = size << conf->chunk_shift;
+ }
+}
static struct r10conf *setup_conf(struct mddev *mddev)
{
struct r10conf *conf = NULL;
int nc, fc, fo;
- sector_t stride, size;
int err = -EINVAL;
if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) ||
@@ -3219,28 +3247,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
if (!conf->r10bio_pool)
goto out;
- size = mddev->dev_sectors >> conf->chunk_shift;
- 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);
-
- conf->dev_sectors = stride << conf->chunk_shift;
-
- if (fo)
- stride = 1;
- else
- sector_div(stride, fc);
- conf->stride = stride << conf->chunk_shift;
-
+ calc_sectors(conf, mddev->dev_sectors);
spin_lock_init(&conf->device_lock);
INIT_LIST_HEAD(&conf->retry_list);
@@ -3468,7 +3475,8 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
mddev->recovery_cp = oldsize;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->dev_sectors = sectors;
+ calc_sectors(conf, sectors);
+ mddev->dev_sectors = conf->dev_sectors;
mddev->resync_max_sectors = size;
return 0;
}