#include "md_p.h"
int Create(char *mddev, int mdfd,
- int chunk, int level, int layout, int size, int raiddisks, int sparedisks,
+ int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force)
{
* if runstop==run, or raiddisks diskswere used,
* RUN_ARRAY
*/
- int minsize, maxsize;
+ unsigned long minsize=0, maxsize=0;
char *mindisc = NULL;
char *maxdisc = NULL;
- int i;
+ int dnum;
mddev_dev_t dv;
int fail=0, warn=0;
struct stat stb;
int first_missing = MD_SB_DISKS*2;
int missing_disks = 0;
int insert_point = MD_SB_DISKS*2; /* where to insert a missing drive */
+ mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */
mdu_array_info_t array;
}
if (raiddisks < 1) {
fprintf(stderr,
- Name ": a number of --raid-disks must be given to create an array\n");
+ Name ": a number of --raid-devices must be given to create an array\n");
return 1;
}
if (raiddisks < 2 && level >= 4) {
fprintf(stderr,
- Name ": atleast 2 raid-disks needed for level 4 or 5\n");
+ Name ": atleast 2 raid-devices needed for level 4 or 5\n");
return 1;
}
if (raiddisks+sparedisks > MD_SB_DISKS) {
fprintf(stderr,
- Name ": too many discs requested: %d+%d > %d\n",
+ Name ": too many devices requested: %d+%d > %d\n",
raiddisks, sparedisks, MD_SB_DISKS);
return 1;
}
if (subdevs > raiddisks+sparedisks) {
- fprintf(stderr, Name ": You have listed more disks (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
+ fprintf(stderr, Name ": You have listed more devices (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
return 1;
}
if (subdevs < raiddisks+sparedisks) {
break;
}
- if (chunk == 0) {
- chunk = 64;
- if (verbose)
- fprintf(stderr, Name ": chunk size defaults to 64K\n");
+ switch(level) {
+ case 4:
+ case 5:
+ case 0:
+ case -1: /* linear */
+ if (chunk == 0) {
+ chunk = 64;
+ if (verbose)
+ fprintf(stderr, Name ": chunk size defaults to 64K\n");
+ }
+ break;
+ default: /* raid1, multipath */
+ if (chunk) {
+ chunk = 0;
+ if (verbose)
+ fprintf(stderr, Name ": chunk size ignored for this level\n");
+ }
+ break;
}
/* now look at the subdevs */
array.active_disks = 0;
array.working_disks = 0;
- for (dv=devlist; dv; dv=dv->next) {
+ dnum = 0;
+ for (dv=devlist; dv; dv=dv->next, dnum++) {
char *dname = dv->devname;
- int dsize, freesize;
+ unsigned long dsize, freesize;
int fd;
if (strcasecmp(dname, "missing")==0) {
- if (first_missing > i)
- first_missing = i;
+ if (first_missing > dnum)
+ first_missing = dnum;
missing_disks ++;
continue;
}
array.working_disks++;
- if (i < raiddisks)
+ if (dnum < raiddisks)
array.active_disks++;
fd = open(dname, O_RDONLY, 0);
if (fd <0 ) {
continue;
}
if (dsize < MD_RESERVED_SECTORS*2) {
- fprintf(stderr, Name ": %s is too small: %dK\n",
+ fprintf(stderr, Name ": %s is too small: %luK\n",
dname, dsize/2);
fail = 1;
close(fd);
if (size && freesize < size) {
fprintf(stderr, Name ": %s is smaller that given size."
- " %dK < %dK + superblock\n", dname, freesize, size);
+ " %luK < %luK + superblock\n", dname, freesize, size);
fail = 1;
close(fd);
continue;
}
size = minsize;
if (verbose && level>0)
- fprintf(stderr, Name ": size set to %dK\n", size);
+ fprintf(stderr, Name ": size set to %luK\n", size);
}
if (level >= 1 && ((maxsize-size)*100 > maxsize)) {
- fprintf(stderr, Name ": largest drive (%s) exceed size (%dK) by more than 1%\n",
+ fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
maxdisc, size);
warn = 1;
}
return 1;
}
- for (i=0, dv = devlist ; dv ; dv=dv->next, i++) {
+ for (dnum=0, dv = devlist ; dv ; dv=(dv->next)?(dv->next):moved_disk, dnum++) {
int fd;
struct stat stb;
mdu_disk_info_t disk;
- disk.number = i;
- if (i >= insert_point)
- disk.number++;
+ disk.number = dnum;
+ if (dnum == insert_point) {
+ moved_disk = dv;
+ }
disk.raid_disk = disk.number;
if (disk.raid_disk < raiddisks)
disk.state = 6; /* active and in sync */
else
disk.state = 0;
- if (strcasecmp(dv->devname, "missing")==0) {
+ if (dnum == insert_point ||
+ strcasecmp(dv->devname, "missing")==0) {
disk.major = 0;
disk.minor = 0;
disk.state = 1; /* faulty */
dv->devname, strerror(errno));
return 1;
}
- }
-
- if (insert_point < MD_SB_DISKS) {
- mdu_disk_info_t disk;
- disk.number = insert_point;
- disk.raid_disk = disk.number;
- disk.state = 1; /* faulty */
- disk.major = disk.minor = 0;
- ioctl(mdfd,ADD_NEW_DISK, &disk);
+ if (dv == moved_disk && dnum != insert_point) break;
}
/* param is not actually used */
}
fprintf(stderr, Name ": array %s started.\n", mddev);
} else {
- fprintf(stderr, Name ": not starting array - not enough discs.\n");
+ fprintf(stderr, Name ": not starting array - not enough devices.\n");
}
return 0;
}