summaryrefslogtreecommitdiffstats
path: root/Create.c
diff options
context:
space:
mode:
Diffstat (limited to 'Create.c')
-rw-r--r--Create.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/Create.c b/Create.c
index 8082f54..d94253b 100644
--- a/Create.c
+++ b/Create.c
@@ -32,6 +32,10 @@
#include <sys/signalfd.h>
#include <sys/wait.h>
+#ifndef FALLOC_FL_ZERO_RANGE
+#define FALLOC_FL_ZERO_RANGE 16
+#endif
+
static int round_size_and_verify(unsigned long long *size, int chunk)
{
if (*size == 0)
@@ -279,8 +283,10 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
dv->devname);
return 1;
}
- if (!fstat_is_blkdev(fd, dv->devname, &rdev))
+ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) {
+ close(fd);
return 1;
+ }
info->disk.major = major(rdev);
info->disk.minor = minor(rdev);
}
@@ -289,6 +295,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
if (st->ss->add_to_super(st, &info->disk, fd, dv->devname,
dv->data_offset)) {
ioctl(mdfd, STOP_ARRAY, NULL);
+ close(fd);
return 1;
}
st->ss->getinfo_super(st, info, NULL);
@@ -297,6 +304,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
*zero_pid = write_zeroes_fork(fd, s, st, dv);
if (*zero_pid <= 0) {
ioctl(mdfd, STOP_ARRAY, NULL);
+ close(fd);
return 1;
}
}
@@ -493,6 +501,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
*/
int mdfd;
unsigned long long minsize = 0, maxsize = 0;
+ dev_policy_t *custom_pols = NULL;
char *mindisc = NULL;
char *maxdisc = NULL;
char *name = ident->name;
@@ -584,6 +593,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
first_missing = subdevs * 2;
second_missing = subdevs * 2;
insert_point = subdevs * 2;
+
+ if (mddev_test_and_add_drive_policies(st, &custom_pols, fd, 1))
+ exit(1);
}
}
if (fd >= 0)
@@ -735,7 +747,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
close(dfd);
exit(2);
}
- close(dfd);
+
info.array.working_disks++;
if (dnum < s->raiddisks && dv->disposition != 'j')
info.array.active_disks++;
@@ -808,6 +820,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
}
}
+ if (drive_test_and_add_policies(st, &custom_pols, dfd, 1))
+ exit(1);
+
+ close(dfd);
+
if (dv->disposition == 'j')
goto skip_size_check; /* skip write journal for size check */
@@ -882,6 +899,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
close(fd);
}
}
+
if (missing_disks == dnum && !have_container) {
pr_err("Subdevs can't be all missing\n");
return 1;
@@ -1136,26 +1154,30 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
goto abort_locked;
}
- if (did_default && c->verbose >= 0) {
+ if (did_default) {
if (is_subarray(info.text_version)) {
- char devnm[32];
- char *ep;
+ char devnm[MD_NAME_MAX];
struct mdinfo *mdi;
- strncpy(devnm, info.text_version+1, 32);
- devnm[31] = 0;
- ep = strchr(devnm, '/');
- if (ep)
- *ep = 0;
+ sysfs_get_container_devnm(&info, devnm);
+
+ mdi = sysfs_read(-1, devnm, GET_VERSION | GET_DEVS);
+ if (!mdi) {
+ pr_err("Cannot open sysfs for container %s\n", devnm);
+ goto abort_locked;
+ }
+
+ if (sysfs_test_and_add_drive_policies(st, &custom_pols, mdi, 1))
+ goto abort_locked;
- mdi = sysfs_read(-1, devnm, GET_VERSION);
+ if (c->verbose >= 0)
+ pr_info("Creating array inside %s container /dev/%s\n",
+ mdi->text_version, devnm);
- pr_info("Creating array inside %s container %s\n",
- mdi?mdi->text_version:"managed", devnm);
sysfs_free(mdi);
- } else
- pr_info("Defaulting to version %s metadata\n",
- info.text_version);
+ } else if (c->verbose >= 0) {
+ pr_info("Defaulting to version %s metadata\n", info.text_version);
+ }
}
map_update(&map, fd2devnm(mdfd), info.text_version,
@@ -1325,6 +1347,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
udev_unblock();
close(mdfd);
sysfs_uevent(&info, "change");
+ dev_policy_free(custom_pols);
+
return 0;
abort:
@@ -1336,5 +1360,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
if (mdfd >= 0)
close(mdfd);
+
+ dev_policy_free(custom_pols);
return 1;
}