int Create(struct supertype *st, char *mddev, int mdfd,
int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
+ char *name,
int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force,
- char *bitmap_file, int bitmap_chunk, int delay)
+ char *bitmap_file, int bitmap_chunk, int write_behind, int delay)
{
/*
* Create a new raid array.
int vers;
int rv;
int bitmap_fd;
+ unsigned long long bitmapsize;
mdu_array_info_t array;
-
+ int major = BITMAP_MAJOR_HI;
+
vers = md_get_version(mdfd);
if (vers < 9000) {
fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
break;
case 10:
layout = 0x102; /* near=2, far=1 */
- if (verbose)
+ if (verbose > 0)
fprintf(stderr,
Name ": layout defaults to n1\n");
break;
case 5:
case 6:
layout = map_name(r5layout, "default");
- if (verbose)
+ if (verbose > 0)
fprintf(stderr,
Name ": layout defaults to %s\n", map_num(r5layout, layout));
break;
case LEVEL_FAULTY:
layout = map_name(faultylayout, "default");
- if (verbose)
+ if (verbose > 0)
fprintf(stderr,
Name ": layout defaults to %s\n", map_num(faultylayout, layout));
break;
case -1: /* linear */
if (chunk == 0) {
chunk = 64;
- if (verbose)
+ if (verbose > 0)
fprintf(stderr, Name ": chunk size defaults to 64K\n");
}
break;
default: /* raid1, multipath */
if (chunk) {
chunk = 0;
- if (verbose)
+ if (verbose > 0)
fprintf(stderr, Name ": chunk size ignored for this level\n");
}
break;
ldsize = dsize;
ldsize <<= 9;
}
- freesize = st->ss->avail_size(ldsize >> 9);
+ freesize = st->ss->avail_size(st, ldsize >> 9);
if (freesize == 0) {
fprintf(stderr, Name ": %s is too small: %luK\n",
dname, (unsigned long)(ldsize>>10));
mindisc = dname;
minsize = freesize;
}
- warn |= check_ext2(fd, dname);
- warn |= check_reiser(fd, dname);
- warn |= check_raid(fd, dname);
+ if (runstop != 1 || verbose >= 0) {
+ warn |= check_ext2(fd, dname);
+ warn |= check_reiser(fd, dname);
+ warn |= check_raid(fd, dname);
+ }
close(fd);
}
if (fail) {
fprintf(stderr, Name ": no size and no drives given - aborting create.\n");
return 1;
}
- if (level > 0) {
+ if (level > 0 || level == LEVEL_MULTIPATH || level == LEVEL_FAULTY) {
/* size is meaningful */
if (minsize > 0x100000000ULL) {
fprintf(stderr, Name ": devices too large for RAID level %d\n", level);
return 1;
}
size = minsize;
- if (verbose)
+ if (verbose > 0)
fprintf(stderr, Name ": size set to %luK\n", size);
}
}
if (level > 0 && ((maxsize-size)*100 > maxsize)) {
- fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
- maxdisc, size);
+ if (runstop != 1 || verbose >= 0)
+ fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
+ maxdisc, size);
warn = 1;
}
return 1;
}
} else {
- if (verbose)
+ if (verbose > 0)
fprintf(stderr, Name ": creation continuing despite oddities due to --run\n");
}
}
else
array.state = 0; /* not clean, but no errors */
+ if (level == 10) {
+ /* for raid10, the bitmap size is the capacity of the array,
+ * which is array.size * raid_disks / ncopies;
+ * .. but convert to sectors.
+ */
+ int ncopies = (layout>>8) * (layout & 255);
+ bitmapsize = (unsigned long long)array.size * raiddisks / ncopies * 2;
+ printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, array.size, raiddisks, ncopies);
+ } else
+ bitmapsize = (unsigned long long)array.size * 2;
+
/* There is lots of redundancy in these disk counts,
* raid_disks is the most meaningful value
* it describes the geometry of the array
array.chunk_size = chunk*1024;
- if (!st->ss->init_super(st, &super, &array))
+ if (!st->ss->init_super(st, &super, &array, name))
return 1;
+ if (bitmap_file && vers < 9003) {
+ major = BITMAP_MAJOR_HOSTENDIAN;
+#ifdef __BIG_ENDIAN
+ fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
+ " between different architectured. Consider upgrading the Linux kernel.\n");
+#endif
+ }
+
if (bitmap_file && strcmp(bitmap_file, "internal")==0) {
if ((vers%100) < 2) {
fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
return 1;
}
- if (!st->ss->add_internal_bitmap(super, bitmap_chunk, delay,
- size ? size : maxsize)) {
+ if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
+ bitmapsize, 1, major)) {
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
return 1;
}
bitmap_chunk = DEFAULT_BITMAP_CHUNK;
st->ss->uuid_from_super(uuid, super);
- if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk, delay,
- array.size*2ULL /* FIXME wrong for raid10 */)) {
+ if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
+ delay, write_behind,
+ bitmapsize,
+ major)) {
return 1;
}
bitmap_fd = open(bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
fprintf(stderr, Name ": weird: %s cannot be openned\n",
- bitmap_file);
+ bitmap_file);
return 1;
}
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
}
disk.raid_disk = disk.number;
if (disk.raid_disk < raiddisks)
- disk.state = 6; /* active and in sync */
+ disk.state = (1<<MD_DISK_ACTIVE) |
+ (1<<MD_DISK_SYNC);
else
disk.state = 0;
+ if (dv->writemostly)
+ disk.state |= (1<<MD_DISK_WRITEMOSTLY);
+
if (dnum == insert_point ||
strcasecmp(dv->devname, "missing")==0) {
disk.major = 0;
disk.minor = 0;
- disk.state = 1; /* faulty */
+ disk.state = (1<<MD_DISK_FAULTY);
} else {
fd = open(dv->devname, O_RDONLY|O_EXCL, 0);
if (fd < 0) {
Manage_runstop(mddev, mdfd, -1, 0);
return 1;
}
- fprintf(stderr, Name ": array %s started.\n", mddev);
+ if (verbose >= 0)
+ fprintf(stderr, Name ": array %s started.\n", mddev);
} else {
fprintf(stderr, Name ": not starting array - not enough devices.\n");
}