diff options
Diffstat (limited to 'sys/contrib/openzfs/cmd/zpool/zpool_vdev.c')
| -rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_vdev.c | 90 | 
1 files changed, 49 insertions, 41 deletions
| diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c index 684b46a2d673..222b5524669e 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c @@ -270,14 +270,13 @@ is_spare(nvlist_t *config, const char *path)   *	draid*		Virtual dRAID spare   */  static nvlist_t * -make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary) +make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)  {  	char path[MAXPATHLEN];  	struct stat64 statbuf;  	nvlist_t *vdev = NULL;  	const char *type = NULL;  	boolean_t wholedisk = B_FALSE; -	uint64_t ashift = 0;  	int err;  	/* @@ -382,31 +381,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)  		    (uint64_t)wholedisk) == 0);  	/* -	 * Override defaults if custom properties are provided. -	 */ -	if (props != NULL) { -		const char *value = NULL; - -		if (nvlist_lookup_string(props, -		    zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) { -			if (zfs_nicestrtonum(NULL, value, &ashift) != 0) { -				(void) fprintf(stderr, -				    gettext("ashift must be a number.\n")); -				return (NULL); -			} -			if (ashift != 0 && -			    (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) { -				(void) fprintf(stderr, -				    gettext("invalid 'ashift=%" PRIu64 "' " -				    "property: only values between %" PRId32 " " -				    "and %" PRId32 " are allowed.\n"), -				    ashift, ASHIFT_MIN, ASHIFT_MAX); -				return (NULL); -			} -		} -	} - -	/*  	 * If the device is known to incorrectly report its physical sector  	 * size explicitly provide the known correct value.  	 */ @@ -609,22 +583,28 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)  				    ZPOOL_CONFIG_PATH, &path) == 0);  				/* +				 * Skip active spares they should never cause +				 * the pool to be evaluated as inconsistent. +				 */ +				if (is_spare(NULL, path)) +					continue; + +				/*  				 * If we have a raidz/mirror that combines disks -				 * with files, report it as an error. +				 * with files, only report it as an error when +				 * fatal is set to ensure all the replication +				 * checks aren't skipped in check_replication().  				 */ -				if (!dontreport && type != NULL && +				if (fatal && !dontreport && type != NULL &&  				    strcmp(type, childtype) != 0) {  					if (ret != NULL)  						free(ret);  					ret = NULL; -					if (fatal) -						vdev_error(gettext( -						    "mismatched replication " -						    "level: %s contains both " -						    "files and devices\n"), -						    rep.zprl_type); -					else -						return (NULL); +					vdev_error(gettext( +					    "mismatched replication " +					    "level: %s contains both " +					    "files and devices\n"), +					    rep.zprl_type);  					dontreport = B_TRUE;  				} @@ -1507,6 +1487,29 @@ construct_spec(nvlist_t *props, int argc, char **argv)  	const char *type, *fulltype;  	boolean_t is_log, is_special, is_dedup, is_spare;  	boolean_t seen_logs; +	uint64_t ashift = 0; + +	if (props != NULL) { +		const char *value = NULL; + +		if (nvlist_lookup_string(props, +		    zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) { +			if (zfs_nicestrtonum(NULL, value, &ashift) != 0) { +				(void) fprintf(stderr, +				    gettext("ashift must be a number.\n")); +				return (NULL); +			} +			if (ashift != 0 && +			    (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) { +				(void) fprintf(stderr, +				    gettext("invalid 'ashift=%" PRIu64 "' " +				    "property: only values between %" PRId32 " " +				    "and %" PRId32 " are allowed.\n"), +				    ashift, ASHIFT_MIN, ASHIFT_MAX); +				return (NULL); +			} +		} +	}  	top = NULL;  	toplevels = 0; @@ -1612,9 +1615,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)  				    children * sizeof (nvlist_t *));  				if (child == NULL)  					zpool_no_memory(); -				if ((nv = make_leaf_vdev(props, argv[c], +				if ((nv = make_leaf_vdev(argv[c],  				    !(is_log || is_special || is_dedup || -				    is_spare))) == NULL) { +				    is_spare), ashift)) == NULL) {  					for (c = 0; c < children - 1; c++)  						nvlist_free(child[c]);  					free(child); @@ -1678,6 +1681,10 @@ construct_spec(nvlist_t *props, int argc, char **argv)  					    ZPOOL_CONFIG_ALLOCATION_BIAS,  					    VDEV_ALLOC_BIAS_DEDUP) == 0);  				} +				if (ashift > 0) { +					fnvlist_add_uint64(nv, +					    ZPOOL_CONFIG_ASHIFT, ashift); +				}  				if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {  					verify(nvlist_add_uint64(nv,  					    ZPOOL_CONFIG_NPARITY, @@ -1705,8 +1712,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)  			 * We have a device.  Pass off to make_leaf_vdev() to  			 * construct the appropriate nvlist describing the vdev.  			 */ -			if ((nv = make_leaf_vdev(props, argv[0], !(is_log || -			    is_special || is_dedup || is_spare))) == NULL) +			if ((nv = make_leaf_vdev(argv[0], !(is_log || +			    is_special || is_dedup || is_spare), +			    ashift)) == NULL)  				goto spec_out;  			verify(nvlist_add_uint64(nv, | 
