Commit d7027458 authored by Neil Brown's avatar Neil Brown Committed by NeilBrown

md: Tidy up rdev_size_store a bit:

 - used strict_strtoull in place of simple_strtoull
 - use my_mddev in place of rdev->mddev (they have the same value)
and more significantly,
 - don't adjust mddev->size to fit, rather reject changes which make
   rdev->size smaller than mddev->size

Adjusting mddev->size is a hangover from bind_rdev_to_array which
does a similar thing.  But it really is a better design to insist that
mddev->size is set as required, then the rdev->sizes are set to allow
for that.  The previous way invites confusion.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 7e93a892
...@@ -347,7 +347,7 @@ Each directory contains: ...@@ -347,7 +347,7 @@ Each directory contains:
for storage of data. This will normally be the same as the for storage of data. This will normally be the same as the
component_size. This can be written while assembling an component_size. This can be written while assembling an
array. If a value less than the current component_size is array. If a value less than the current component_size is
written, component_size will be reduced to this value. written, it will be rejected.
An active md device will also contain and entry for each active device An active md device will also contain and entry for each active device
......
...@@ -2101,16 +2101,17 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2) ...@@ -2101,16 +2101,17 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
static ssize_t static ssize_t
rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{ {
char *e; unsigned long long size;
unsigned long long size = simple_strtoull(buf, &e, 10);
unsigned long long oldsize = rdev->size; unsigned long long oldsize = rdev->size;
mddev_t *my_mddev = rdev->mddev; mddev_t *my_mddev = rdev->mddev;
if (e==buf || (*e && *e != '\n')) if (strict_strtoull(buf, 10, &size) < 0)
return -EINVAL;
if (size < my_mddev->size)
return -EINVAL; return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) { if (my_mddev->pers && rdev->raid_disk >= 0) {
if (rdev->mddev->persistent) { if (my_mddev->persistent) {
size = super_types[rdev->mddev->major_version]. size = super_types[my_mddev->major_version].
rdev_size_change(rdev, size); rdev_size_change(rdev, size);
if (!size) if (!size)
return -EBUSY; return -EBUSY;
...@@ -2118,12 +2119,12 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2118,12 +2119,12 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
size = (rdev->bdev->bd_inode->i_size >> 10); size = (rdev->bdev->bd_inode->i_size >> 10);
size -= rdev->data_offset/2; size -= rdev->data_offset/2;
} }
if (size < rdev->mddev->size) if (size < my_mddev->size)
return -EINVAL; /* component must fit device */ return -EINVAL; /* component must fit device */
} }
rdev->size = size; rdev->size = size;
if (size > oldsize && rdev->mddev->external) { if (size > oldsize && my_mddev->external) {
/* need to check that all other rdevs with the same ->bdev /* need to check that all other rdevs with the same ->bdev
* do not overlap. We need to unlock the mddev to avoid * do not overlap. We need to unlock the mddev to avoid
* a deadlock. We have already changed rdev->size, and if * a deadlock. We have already changed rdev->size, and if
...@@ -2165,8 +2166,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2165,8 +2166,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EBUSY; return -EBUSY;
} }
} }
if (size < my_mddev->size || my_mddev->size == 0)
my_mddev->size = size;
return len; return len;
} }
......
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