mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 19:28:53 +03:00
Rebase master to b121
This commit is contained in:
+35
-12
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include <libdiskmgt.h>
|
||||
#include <libintl.h>
|
||||
#include <libnvpair.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -1093,19 +1094,34 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
|
||||
}
|
||||
|
||||
static const char *
|
||||
is_grouping(const char *type, int *mindev)
|
||||
is_grouping(const char *type, int *mindev, int *maxdev)
|
||||
{
|
||||
if (strcmp(type, "raidz") == 0 || strcmp(type, "raidz1") == 0) {
|
||||
if (strncmp(type, "raidz", 5) == 0) {
|
||||
const char *p = type + 5;
|
||||
char *end;
|
||||
long nparity;
|
||||
|
||||
if (*p == '\0') {
|
||||
nparity = 1;
|
||||
} else if (*p == '0') {
|
||||
return (NULL); /* no zero prefixes allowed */
|
||||
} else {
|
||||
errno = 0;
|
||||
nparity = strtol(p, &end, 10);
|
||||
if (errno != 0 || nparity < 1 || nparity >= 255 ||
|
||||
*end != '\0')
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (mindev != NULL)
|
||||
*mindev = 2;
|
||||
*mindev = nparity + 1;
|
||||
if (maxdev != NULL)
|
||||
*maxdev = 255;
|
||||
return (VDEV_TYPE_RAIDZ);
|
||||
}
|
||||
|
||||
if (strcmp(type, "raidz2") == 0) {
|
||||
if (mindev != NULL)
|
||||
*mindev = 3;
|
||||
return (VDEV_TYPE_RAIDZ);
|
||||
}
|
||||
if (maxdev != NULL)
|
||||
*maxdev = INT_MAX;
|
||||
|
||||
if (strcmp(type, "mirror") == 0) {
|
||||
if (mindev != NULL)
|
||||
@@ -1144,7 +1160,7 @@ nvlist_t *
|
||||
construct_spec(int argc, char **argv)
|
||||
{
|
||||
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
|
||||
int t, toplevels, mindev, nspares, nlogs, nl2cache;
|
||||
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
|
||||
const char *type;
|
||||
uint64_t is_log;
|
||||
boolean_t seen_logs;
|
||||
@@ -1166,7 +1182,7 @@ construct_spec(int argc, char **argv)
|
||||
* If it's a mirror or raidz, the subsequent arguments are
|
||||
* its leaves -- until we encounter the next mirror or raidz.
|
||||
*/
|
||||
if ((type = is_grouping(argv[0], &mindev)) != NULL) {
|
||||
if ((type = is_grouping(argv[0], &mindev, &maxdev)) != NULL) {
|
||||
nvlist_t **child = NULL;
|
||||
int c, children = 0;
|
||||
|
||||
@@ -1223,7 +1239,7 @@ construct_spec(int argc, char **argv)
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (is_grouping(argv[c], NULL) != NULL)
|
||||
if (is_grouping(argv[c], NULL, NULL) != NULL)
|
||||
break;
|
||||
children++;
|
||||
child = realloc(child,
|
||||
@@ -1243,6 +1259,13 @@ construct_spec(int argc, char **argv)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (children > maxdev) {
|
||||
(void) fprintf(stderr, gettext("invalid vdev "
|
||||
"specification: %s supports no more than "
|
||||
"%d devices\n"), argv[0], maxdev);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
argc -= c;
|
||||
argv += c;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user