#include "md_p.h"
#include <ctype.h>
+static int round_size_and_verify(unsigned long long *size, int chunk)
+{
+ if (*size == 0)
+ return 0;
+ *size &= ~(unsigned long long)(chunk - 1);
+ if (*size == 0) {
+ pr_err("Size cannot be smaller than chunk.\n");
+ return 1;
+ }
+ return 0;
+}
+
static int default_layout(struct supertype *st, int level, int verbose)
{
int layout = UnSet;
char *maxdisc = NULL;
int dnum, raid_disk_num;
struct mddev_dev *dv;
+ dev_t rdev;
int fail = 0, warn = 0;
- struct stat stb;
int first_missing = subdevs * 2;
int second_missing = subdevs * 2;
int missing_disks = 0;
pr_err("unknown level %d\n", s->level);
return 1;
}
+
if (s->size == MAX_SIZE)
/* use '0' to mean 'max' now... */
s->size = 0;
if (s->size && s->chunk && s->chunk != UnSet)
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
+
newsize = s->size * 2;
if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
&s->chunk, s->size*2,
/* default chunk was just set */
if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s->chunk);
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
do_default_chunk = 0;
}
}
dname, strerror(errno));
exit(2);
}
- if (fstat(dfd, &stb) != 0 ||
- (stb.st_mode & S_IFMT) != S_IFBLK) {
+ if (!fstat_is_blkdev(dfd, dname, NULL)) {
close(dfd);
- pr_err("%s is not a block device\n",
- dname);
exit(2);
}
close(dfd);
/* default chunk was just set */
if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s->chunk);
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
do_default_chunk = 0;
}
}
close(fd);
}
}
+ if (missing_disks == dnum && !have_container) {
+ pr_err("Subdevs can't be all missing\n");
+ return 1;
+ }
if (s->raiddisks + s->sparedisks > st->max_devs) {
pr_err("Too many devices: %s metadata only supports %d\n",
st->ss->name, st->max_devs);
* with, but it chooses to trust me instead. Sigh
*/
info.array.md_minor = 0;
- if (fstat(mdfd, &stb) == 0)
- info.array.md_minor = minor(stb.st_rdev);
+ if (fstat_is_blkdev(mdfd, mddev, &rdev))
+ info.array.md_minor = minor(rdev);
info.array.not_persistent = 0;
if (((s->level == 4 || s->level == 5) &&
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
- pr_err("weird: %s cannot be openned\n",
+ pr_err("weird: %s cannot be opened\n",
s->bitmap_file);
goto abort_locked;
}
for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
int fd;
- struct stat stb2;
struct mdinfo *inf = &infos[dnum];
if (dnum >= total_slots)
dv->devname);
goto abort_locked;
}
- fstat(fd, &stb2);
- inf->disk.major = major(stb2.st_rdev);
- inf->disk.minor = minor(stb2.st_rdev);
+ if (!fstat_is_blkdev(fd, dv->devname, &rdev))
+ return 1;
+ inf->disk.major = major(rdev);
+ inf->disk.minor = minor(rdev);
}
if (fd >= 0)
remove_partitions(fd);
if (!have_container) {
/* getinfo_super might have lost these ... */
- inf->disk.major = major(stb2.st_rdev);
- inf->disk.minor = minor(stb2.st_rdev);
+ inf->disk.major = major(rdev);
+ inf->disk.minor = minor(rdev);
}
break;
case 2: