+
+static int reserve_space(struct supertype *st, int raiddisks,
+ unsigned long long size, int chunk,
+ unsigned long long *freesize)
+{
+ /* Find 'raiddisks' spare extents at least 'size' big (but
+ * only caring about multiples of 'chunk') and remember
+ * them.
+ * If the cannot be found, fail.
+ */
+ struct dl *dl;
+ struct ddf_super *ddf = st->sb;
+ int cnt = 0;
+
+ for (dl = ddf->dlist; dl ; dl=dl->next) {
+ dl->raiddisk = -1;
+ dl->esize = 0;
+ }
+ /* Now find largest extent on each device */
+ for (dl = ddf->dlist ; dl ; dl=dl->next) {
+ struct extent *e = get_extents(ddf, dl);
+ unsigned long long pos = 0;
+ int i = 0;
+ int found = 0;
+ unsigned long long minsize = size;
+
+ if (size == 0)
+ minsize = chunk;
+
+ if (!e)
+ continue;
+ do {
+ unsigned long long esize;
+ esize = e[i].start - pos;
+ if (esize >= minsize) {
+ found = 1;
+ minsize = esize;
+ }
+ pos = e[i].start + e[i].size;
+ i++;
+ } while (e[i-1].size);
+ if (found) {
+ cnt++;
+ dl->esize = minsize;
+ }
+ free(e);
+ }
+ if (cnt < raiddisks) {
+ fprintf(stderr, Name ": not enough devices with space to create array.\n");
+ return 0; /* No enough free spaces large enough */
+ }
+ if (size == 0) {
+ /* choose the largest size of which there are at least 'raiddisk' */
+ for (dl = ddf->dlist ; dl ; dl=dl->next) {
+ struct dl *dl2;
+ if (dl->esize <= size)
+ continue;
+ /* This is bigger than 'size', see if there are enough */
+ cnt = 0;
+ for (dl2 = dl; dl2 ; dl2=dl2->next)
+ if (dl2->esize >= dl->esize)
+ cnt++;
+ if (cnt >= raiddisks)
+ size = dl->esize;
+ }
+ if (chunk) {
+ size = size / chunk;
+ size *= chunk;
+ }
+ *freesize = size;
+ if (size < 32) {
+ fprintf(stderr, Name ": not enough spare devices to create array.\n");
+ return 0;
+ }
+ }
+ /* We have a 'size' of which there are enough spaces.
+ * We simply do a first-fit */
+ cnt = 0;
+ for (dl = ddf->dlist ; dl && cnt < raiddisks ; dl=dl->next) {
+ if (dl->esize < size)
+ continue;
+
+ dl->raiddisk = cnt;
+ cnt++;
+ }
+ return 1;
+}
+
+
+
+static int
+validate_geometry_ddf_container(struct supertype *st,
+ int level, int layout, int raiddisks,
+ int chunk, unsigned long long size,
+ char *dev, unsigned long long *freesize,
+ int verbose);
+
+static int validate_geometry_ddf_bvd(struct supertype *st,
+ int level, int layout, int raiddisks,
+ int chunk, unsigned long long size,
+ char *dev, unsigned long long *freesize,
+ int verbose);
+
+static int validate_geometry_ddf(struct supertype *st,
+ int level, int layout, int raiddisks,
+ int chunk, unsigned long long size,
+ char *dev, unsigned long long *freesize,
+ int verbose)