Check device is large enough before hot-add.

This improves quality of error message.
This commit is contained in:
Neil Brown 2006-12-14 17:32:49 +11:00
parent c5a6f9a61d
commit 4a39c6f236
2 changed files with 37 additions and 1 deletions

View File

@ -23,6 +23,8 @@ Changes Prior to this release
- If two drives in a raid5 disappear at the same time, then "-Af"
will add them both in rather than just one and forcing the array
to 'clean'. This is slightly safer in some cases.
- Check device is large enough before hot-add: this improves quality
of error message.
Changes Prior to 2.5.6 release
- Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled

View File

@ -186,6 +186,9 @@ int Manage_subdevs(char *devname, int fd,
return 1;
}
for (dv = devlist ; dv; dv=dv->next) {
unsigned long long ldsize;
unsigned long dsize;
if (stat(dv->devname, &stb)) {
fprintf(stderr, Name ": cannot find %s: %s\n",
dv->devname, strerror(errno));
@ -202,7 +205,7 @@ int Manage_subdevs(char *devname, int fd,
dv->devname, dv->disposition);
return 1;
case 'a':
/* add the device - hot or cold */
/* add the device */
st = super_by_version(array.major_version,
array.minor_version);
if (!st) {
@ -221,6 +224,20 @@ int Manage_subdevs(char *devname, int fd,
if (array.not_persistent==0)
st->ss->load_super(st, tfd, &osuper, NULL);
/* will use osuper later */
#ifdef BLKGETSIZE64
if (ioctl(tfd, BLKGETSIZE64, &ldsize)==0)
;
else
#endif
if (ioctl(tfd, BLKGETSIZE, &dsize)) {
fprintf(stderr, Name ": Cannot get size of %s: %s\n",
dv->devname, strerror(errno));
close(tfd);
return 1;
} else {
ldsize = dsize;
ldsize <<= 9;
}
close(tfd);
if (array.major_version == 0 &&
@ -240,6 +257,14 @@ int Manage_subdevs(char *devname, int fd,
if (array.not_persistent == 0) {
/* Make sure device is large enough */
if (st->ss->avail_size(st, ldsize/512) <
array.size) {
fprintf(stderr, Name ": %s not large enough to join array\n",
dv->devname);
return 1;
}
/* need to find a sample superblock to copy, and
* a spare slot to use
*/
@ -303,6 +328,15 @@ int Manage_subdevs(char *devname, int fd,
/* fall back on normal-add */
}
}
} else {
/* non-persistent. Must ensure that new drive
* is at least array.size big.
*/
if (ldsize/512 < array.size) {
fprintf(stderr, Name ": %s not large enough to join array\n",
dv->devname);
return 1;
}
}
/* in 2.6.17 and earlier, version-1 superblocks won't
* use the number we write, but will choose a free number.