Commit 80c3a6ce authored by Dan Williams's avatar Dan Williams

md: add 'size' as a personality method

In preparation for giving userspace control over ->array_sectors we need
to be able to retrieve the 'default' size, and the 'anticipated' size
when a reshape is requested.  For personalities that do not reshape emit
a warning if anything but the default size is requested.

In the raid5 case we need to update ->previous_raid_disks to make the
new 'default' size available.
Reviewed-by: default avatarAndre Noll <maan@systemlinux.org>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 93ed05e2
...@@ -283,6 +283,17 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size) ...@@ -283,6 +283,17 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size)
return 0; return 0;
} }
static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
WARN_ONCE(raid_disks,
"%s does not support generic reshape\n", __func__);
if (sectors == 0)
return mddev->dev_sectors;
return sectors;
}
static int run(mddev_t *mddev) static int run(mddev_t *mddev)
{ {
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
...@@ -301,7 +312,7 @@ static int run(mddev_t *mddev) ...@@ -301,7 +312,7 @@ static int run(mddev_t *mddev)
list_for_each_entry(rdev, &mddev->disks, same_set) list_for_each_entry(rdev, &mddev->disks, same_set)
conf->rdev = rdev; conf->rdev = rdev;
mddev->array_sectors = mddev->dev_sectors; mddev->array_sectors = faulty_size(mddev, 0, 0);
mddev->private = conf; mddev->private = conf;
reconfig(mddev, mddev->layout, -1); reconfig(mddev, mddev->layout, -1);
...@@ -328,6 +339,7 @@ static struct mdk_personality faulty_personality = ...@@ -328,6 +339,7 @@ static struct mdk_personality faulty_personality =
.stop = stop, .stop = stop,
.status = status, .status = status,
.reconfig = reconfig, .reconfig = reconfig,
.size = faulty_size,
}; };
static int __init raid_init(void) static int __init raid_init(void)
......
...@@ -101,6 +101,16 @@ static int linear_congested(void *data, int bits) ...@@ -101,6 +101,16 @@ static int linear_congested(void *data, int bits)
return ret; return ret;
} }
static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
linear_conf_t *conf = mddev_to_conf(mddev);
WARN_ONCE(sectors || raid_disks,
"%s does not support generic reshape\n", __func__);
return conf->array_sectors;
}
static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
{ {
linear_conf_t *conf; linear_conf_t *conf;
...@@ -253,7 +263,7 @@ static int linear_run (mddev_t *mddev) ...@@ -253,7 +263,7 @@ static int linear_run (mddev_t *mddev)
if (!conf) if (!conf)
return 1; return 1;
mddev->private = conf; mddev->private = conf;
mddev->array_sectors = conf->array_sectors; mddev->array_sectors = linear_size(mddev, 0, 0);
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug; mddev->queue->unplug_fn = linear_unplug;
...@@ -287,7 +297,7 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -287,7 +297,7 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
newconf->prev = mddev_to_conf(mddev); newconf->prev = mddev_to_conf(mddev);
mddev->private = newconf; mddev->private = newconf;
mddev->raid_disks++; mddev->raid_disks++;
mddev->array_sectors = newconf->array_sectors; mddev->array_sectors = linear_size(mddev, 0, 0);
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
return 0; return 0;
} }
...@@ -385,6 +395,7 @@ static struct mdk_personality linear_personality = ...@@ -385,6 +395,7 @@ static struct mdk_personality linear_personality =
.stop = linear_stop, .stop = linear_stop,
.status = linear_status, .status = linear_status,
.hot_add_disk = linear_add, .hot_add_disk = linear_add,
.size = linear_size,
}; };
static int __init linear_init (void) static int __init linear_init (void)
......
...@@ -312,6 +312,7 @@ struct mdk_personality ...@@ -312,6 +312,7 @@ struct mdk_personality
int (*spare_active) (mddev_t *mddev); int (*spare_active) (mddev_t *mddev);
sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster); sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
int (*resize) (mddev_t *mddev, sector_t sectors); int (*resize) (mddev_t *mddev, sector_t sectors);
sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
int (*check_reshape) (mddev_t *mddev); int (*check_reshape) (mddev_t *mddev);
int (*start_reshape) (mddev_t *mddev); int (*start_reshape) (mddev_t *mddev);
int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
......
...@@ -406,6 +406,14 @@ static void multipathd (mddev_t *mddev) ...@@ -406,6 +406,14 @@ static void multipathd (mddev_t *mddev)
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
} }
static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
WARN_ONCE(sectors || raid_disks,
"%s does not support generic reshape\n", __func__);
return mddev->dev_sectors;
}
static int multipath_run (mddev_t *mddev) static int multipath_run (mddev_t *mddev)
{ {
multipath_conf_t *conf; multipath_conf_t *conf;
...@@ -502,7 +510,7 @@ static int multipath_run (mddev_t *mddev) ...@@ -502,7 +510,7 @@ static int multipath_run (mddev_t *mddev)
/* /*
* Ok, everything is just fine now * Ok, everything is just fine now
*/ */
mddev->array_sectors = mddev->dev_sectors; mddev->array_sectors = multipath_size(mddev, 0, 0);
mddev->queue->unplug_fn = multipath_unplug; mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->backing_dev_info.congested_fn = multipath_congested; mddev->queue->backing_dev_info.congested_fn = multipath_congested;
...@@ -547,6 +555,7 @@ static struct mdk_personality multipath_personality = ...@@ -547,6 +555,7 @@ static struct mdk_personality multipath_personality =
.error_handler = multipath_error, .error_handler = multipath_error,
.hot_add_disk = multipath_add_disk, .hot_add_disk = multipath_add_disk,
.hot_remove_disk= multipath_remove_disk, .hot_remove_disk= multipath_remove_disk,
.size = multipath_size,
}; };
static int __init multipath_init (void) static int __init multipath_init (void)
......
...@@ -263,12 +263,25 @@ static int raid0_mergeable_bvec(struct request_queue *q, ...@@ -263,12 +263,25 @@ static int raid0_mergeable_bvec(struct request_queue *q,
return max; return max;
} }
static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
sector_t array_sectors = 0;
mdk_rdev_t *rdev;
WARN_ONCE(sectors || raid_disks,
"%s does not support generic reshape\n", __func__);
list_for_each_entry(rdev, &mddev->disks, same_set)
array_sectors += rdev->sectors;
return array_sectors;
}
static int raid0_run (mddev_t *mddev) static int raid0_run (mddev_t *mddev)
{ {
unsigned cur=0, i=0, nb_zone; unsigned cur=0, i=0, nb_zone;
s64 sectors; s64 sectors;
raid0_conf_t *conf; raid0_conf_t *conf;
mdk_rdev_t *rdev;
if (mddev->chunk_size == 0) { if (mddev->chunk_size == 0) {
printk(KERN_ERR "md/raid0: non-zero chunk size required.\n"); printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
...@@ -293,9 +306,7 @@ static int raid0_run (mddev_t *mddev) ...@@ -293,9 +306,7 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf; goto out_free_conf;
/* calculate array device size */ /* calculate array device size */
mddev->array_sectors = 0; mddev->array_sectors = raid0_size(mddev, 0, 0);
list_for_each_entry(rdev, &mddev->disks, same_set)
mddev->array_sectors += rdev->sectors;
printk(KERN_INFO "raid0 : md_size is %llu sectors.\n", printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
(unsigned long long)mddev->array_sectors); (unsigned long long)mddev->array_sectors);
...@@ -511,6 +522,7 @@ static struct mdk_personality raid0_personality= ...@@ -511,6 +522,7 @@ static struct mdk_personality raid0_personality=
.run = raid0_run, .run = raid0_run,
.stop = raid0_stop, .stop = raid0_stop,
.status = raid0_status, .status = raid0_status,
.size = raid0_size,
}; };
static int __init raid0_init (void) static int __init raid0_init (void)
......
...@@ -1922,6 +1922,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i ...@@ -1922,6 +1922,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return nr_sectors; return nr_sectors;
} }
static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
if (sectors)
return sectors;
return mddev->dev_sectors;
}
static int run(mddev_t *mddev) static int run(mddev_t *mddev)
{ {
conf_t *conf; conf_t *conf;
...@@ -2051,7 +2059,7 @@ static int run(mddev_t *mddev) ...@@ -2051,7 +2059,7 @@ static int run(mddev_t *mddev)
/* /*
* Ok, everything is just fine now * Ok, everything is just fine now
*/ */
mddev->array_sectors = mddev->dev_sectors; mddev->array_sectors = raid1_size(mddev, 0, 0);
mddev->queue->unplug_fn = raid1_unplug; mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->backing_dev_info.congested_fn = raid1_congested; mddev->queue->backing_dev_info.congested_fn = raid1_congested;
...@@ -2116,7 +2124,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) ...@@ -2116,7 +2124,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems * any io in the removed space completes, but it hardly seems
* worth it. * worth it.
*/ */
mddev->array_sectors = sectors; mddev->array_sectors = raid1_size(mddev, sectors, 0);
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1; mddev->changed = 1;
if (mddev->array_sectors > mddev->dev_sectors && if (mddev->array_sectors > mddev->dev_sectors &&
...@@ -2270,6 +2278,7 @@ static struct mdk_personality raid1_personality = ...@@ -2270,6 +2278,7 @@ static struct mdk_personality raid1_personality =
.spare_active = raid1_spare_active, .spare_active = raid1_spare_active,
.sync_request = sync_request, .sync_request = sync_request,
.resize = raid1_resize, .resize = raid1_resize,
.size = raid1_size,
.check_reshape = raid1_reshape, .check_reshape = raid1_reshape,
.quiesce = raid1_quiesce, .quiesce = raid1_quiesce,
}; };
......
...@@ -2023,6 +2023,25 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i ...@@ -2023,6 +2023,25 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
goto skipped; goto skipped;
} }
static sector_t
raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
sector_t size;
conf_t *conf = mddev_to_conf(mddev);
if (!raid_disks)
raid_disks = mddev->raid_disks;
if (!sectors)
sectors = mddev->dev_sectors;
size = sectors >> conf->chunk_shift;
sector_div(size, conf->far_copies);
size = size * raid_disks;
sector_div(size, conf->near_copies);
return size << conf->chunk_shift;
}
static int run(mddev_t *mddev) static int run(mddev_t *mddev)
{ {
conf_t *conf; conf_t *conf;
...@@ -2174,8 +2193,8 @@ static int run(mddev_t *mddev) ...@@ -2174,8 +2193,8 @@ static int run(mddev_t *mddev)
/* /*
* Ok, everything is just fine now * Ok, everything is just fine now
*/ */
mddev->array_sectors = size << conf->chunk_shift; mddev->array_sectors = raid10_size(mddev, 0, 0);
mddev->resync_max_sectors = size << conf->chunk_shift; mddev->resync_max_sectors = mddev->array_sectors;
mddev->queue->unplug_fn = raid10_unplug; mddev->queue->unplug_fn = raid10_unplug;
mddev->queue->backing_dev_info.congested_fn = raid10_congested; mddev->queue->backing_dev_info.congested_fn = raid10_congested;
...@@ -2261,6 +2280,7 @@ static struct mdk_personality raid10_personality = ...@@ -2261,6 +2280,7 @@ static struct mdk_personality raid10_personality =
.spare_active = raid10_spare_active, .spare_active = raid10_spare_active,
.sync_request = sync_request, .sync_request = sync_request,
.quiesce = raid10_quiesce, .quiesce = raid10_quiesce,
.size = raid10_size,
}; };
static int __init raid_init(void) static int __init raid_init(void)
......
...@@ -4166,6 +4166,20 @@ static struct attribute_group raid5_attrs_group = { ...@@ -4166,6 +4166,20 @@ static struct attribute_group raid5_attrs_group = {
.attrs = raid5_attrs, .attrs = raid5_attrs,
}; };
static sector_t
raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
if (!sectors)
sectors = mddev->dev_sectors;
if (!raid_disks)
raid_disks = conf->previous_raid_disks;
sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
return sectors * (raid_disks - conf->max_degraded);
}
static raid5_conf_t *setup_conf(mddev_t *mddev) static raid5_conf_t *setup_conf(mddev_t *mddev)
{ {
raid5_conf_t *conf; raid5_conf_t *conf;
...@@ -4460,8 +4474,7 @@ static int run(mddev_t *mddev) ...@@ -4460,8 +4474,7 @@ static int run(mddev_t *mddev)
mddev->queue->backing_dev_info.congested_data = mddev; mddev->queue->backing_dev_info.congested_data = mddev;
mddev->queue->backing_dev_info.congested_fn = raid5_congested; mddev->queue->backing_dev_info.congested_fn = raid5_congested;
mddev->array_sectors = mddev->dev_sectors * mddev->array_sectors = raid5_size(mddev, 0, 0);
(conf->previous_raid_disks - conf->max_degraded);
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
...@@ -4684,11 +4697,8 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) ...@@ -4684,11 +4697,8 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems * any io in the removed space completes, but it hardly seems
* worth it. * worth it.
*/ */
raid5_conf_t *conf = mddev_to_conf(mddev);
sectors &= ~((sector_t)mddev->chunk_size/512 - 1); sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
mddev->array_sectors = sectors * (mddev->raid_disks mddev->array_sectors = raid5_size(mddev, sectors, mddev->raid_disks);
- conf->max_degraded);
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1; mddev->changed = 1;
if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) { if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
...@@ -4824,10 +4834,12 @@ static void end_reshape(raid5_conf_t *conf) ...@@ -4824,10 +4834,12 @@ static void end_reshape(raid5_conf_t *conf)
struct block_device *bdev; struct block_device *bdev;
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
conf->mddev->array_sectors = conf->mddev->dev_sectors * mddev_t *mddev = conf->mddev;
(conf->raid_disks - conf->max_degraded);
set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors); mddev->array_sectors = raid5_size(mddev, 0, conf->raid_disks);
conf->mddev->changed = 1; set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
conf->previous_raid_disks = conf->raid_disks;
bdev = bdget_disk(conf->mddev->gendisk, 0); bdev = bdget_disk(conf->mddev->gendisk, 0);
if (bdev) { if (bdev) {
...@@ -5076,6 +5088,7 @@ static struct mdk_personality raid6_personality = ...@@ -5076,6 +5088,7 @@ static struct mdk_personality raid6_personality =
.spare_active = raid5_spare_active, .spare_active = raid5_spare_active,
.sync_request = sync_request, .sync_request = sync_request,
.resize = raid5_resize, .resize = raid5_resize,
.size = raid5_size,
#ifdef CONFIG_MD_RAID5_RESHAPE #ifdef CONFIG_MD_RAID5_RESHAPE
.check_reshape = raid5_check_reshape, .check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape, .start_reshape = raid5_start_reshape,
...@@ -5098,6 +5111,7 @@ static struct mdk_personality raid5_personality = ...@@ -5098,6 +5111,7 @@ static struct mdk_personality raid5_personality =
.spare_active = raid5_spare_active, .spare_active = raid5_spare_active,
.sync_request = sync_request, .sync_request = sync_request,
.resize = raid5_resize, .resize = raid5_resize,
.size = raid5_size,
#ifdef CONFIG_MD_RAID5_RESHAPE #ifdef CONFIG_MD_RAID5_RESHAPE
.check_reshape = raid5_check_reshape, .check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape, .start_reshape = raid5_start_reshape,
...@@ -5122,6 +5136,7 @@ static struct mdk_personality raid4_personality = ...@@ -5122,6 +5136,7 @@ static struct mdk_personality raid4_personality =
.spare_active = raid5_spare_active, .spare_active = raid5_spare_active,
.sync_request = sync_request, .sync_request = sync_request,
.resize = raid5_resize, .resize = raid5_resize,
.size = raid5_size,
#ifdef CONFIG_MD_RAID5_RESHAPE #ifdef CONFIG_MD_RAID5_RESHAPE
.check_reshape = raid5_check_reshape, .check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape, .start_reshape = raid5_start_reshape,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment