aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-03-31 00:00:31 -0400
committerDan Williams <dan.j.williams@intel.com>2009-03-31 00:00:31 -0400
commitb522adcde9c4d3fb7b579cfa9160d8bde7744be8 (patch)
tree4208e3dcec3ebdfa6ad9bc153f76129400532717 /drivers/md/raid5.c
parent1f403624bde3c678a166984b1e6a727a0ce06f2b (diff)
md: 'array_size' sysfs attribute
Allow userspace to set the size of the array according to the following semantics: 1/ size must be <= to the size returned by mddev->pers->size(mddev, 0, 0) a) If size is set before the array is running, do_md_run will fail if size is greater than the default size b) A reshape attempt that reduces the default size to less than the set array size should be blocked 2/ once userspace sets the size the kernel will not change it 3/ writing 'default' to this attribute returns control of the size to the kernel and reverts to the size reported by the personality Also, convert locations that need to know the default size from directly reading ->array_sectors to <pers>_size. Resync/reshape operations always follow the default size. Finally, fixup other locations that read a number of 1k-blocks from userspace to use strict_blocks_to_sectors() which checks for unsigned long long to sector_t overflow and blocks to sectors overflow. Reviewed-by: Andre Noll <maan@systemlinux.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2930fc26a852..1aebd3ef80b7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3703,6 +3703,8 @@ static int make_request(struct request_queue *q, struct bio * bi)
3703 return 0; 3703 return 0;
3704} 3704}
3705 3705
3706static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
3707
3706static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped) 3708static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
3707{ 3709{
3708 /* reshaping is quite different to recovery/resync so it is 3710 /* reshaping is quite different to recovery/resync so it is
@@ -3781,7 +3783,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3781 j == sh->qd_idx) 3783 j == sh->qd_idx)
3782 continue; 3784 continue;
3783 s = compute_blocknr(sh, j); 3785 s = compute_blocknr(sh, j);
3784 if (s < mddev->array_sectors) { 3786 if (s < raid5_size(mddev, 0, 0)) {
3785 skipped = 1; 3787 skipped = 1;
3786 continue; 3788 continue;
3787 } 3789 }
@@ -4700,6 +4702,9 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
4700 sectors &= ~((sector_t)mddev->chunk_size/512 - 1); 4702 sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
4701 md_set_array_sectors(mddev, raid5_size(mddev, sectors, 4703 md_set_array_sectors(mddev, raid5_size(mddev, sectors,
4702 mddev->raid_disks)); 4704 mddev->raid_disks));
4705 if (mddev->array_sectors >
4706 raid5_size(mddev, sectors, mddev->raid_disks))
4707 return -EINVAL;
4703 set_capacity(mddev->gendisk, mddev->array_sectors); 4708 set_capacity(mddev->gendisk, mddev->array_sectors);
4704 mddev->changed = 1; 4709 mddev->changed = 1;
4705 if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) { 4710 if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
@@ -4837,7 +4842,7 @@ static void end_reshape(raid5_conf_t *conf)
4837 if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { 4842 if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
4838 mddev_t *mddev = conf->mddev; 4843 mddev_t *mddev = conf->mddev;
4839 4844
4840 md_set_array_sectors(mddev, raid5_size(mddev, 0, 4845 md_set_array_sectors_lock(mddev, raid5_size(mddev, 0,
4841 conf->raid_disks)); 4846 conf->raid_disks));
4842 set_capacity(mddev->gendisk, mddev->array_sectors); 4847 set_capacity(mddev->gendisk, mddev->array_sectors);
4843 mddev->changed = 1; 4848 mddev->changed = 1;