changeset 13680:2bd022a765e2

2665 sd.conf should be able to override physical-block-size 2671 zpool import should not fail if vdev ashift has increased Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Eric Schrock <eric.schrock@delphix.com> Reviewed by: Richard Elling <richard.elling@richardelling.com> Reviewed by: Gordon Ross <gwr@nexenta.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Richard Lowe <richlowe@richlowe.net>
author George Wilson <gwilson@delphix.com>
date Thu, 03 May 2012 05:49:19 -0700
parents 1b5898b11b55
children 73253247f9e5
files usr/src/cmd/zpool/zpool_main.c usr/src/uts/common/fs/zfs/vdev.c usr/src/uts/common/io/scsi/targets/sd.c
diffstat 3 files changed, 42 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/zpool/zpool_main.c	Tue May 01 21:27:17 2012 +0100
+++ b/usr/src/cmd/zpool/zpool_main.c	Thu May 03 05:49:19 2012 -0700
@@ -3703,7 +3703,7 @@
 
 	/*
 	 * If the pool was faulted then we may not have been able to
-	 * obtain the config. Otherwise, if have anything in the dedup
+	 * obtain the config. Otherwise, if we have anything in the dedup
 	 * table continue processing the stats.
 	 */
 	if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
--- a/usr/src/uts/common/fs/zfs/vdev.c	Tue May 01 21:27:17 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/vdev.c	Thu May 03 05:49:19 2012 -0700
@@ -1244,12 +1244,16 @@
 		vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
 	} else {
 		/*
-		 * Make sure the alignment requirement hasn't increased.
+		 * Detect if the alignment requirement has increased.
+		 * We don't want to make the pool unavailable, just
+		 * issue a warning instead.
 		 */
-		if (ashift > vd->vdev_top->vdev_ashift) {
-			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
-			    VDEV_AUX_BAD_LABEL);
-			return (EINVAL);
+		if (ashift > vd->vdev_top->vdev_ashift &&
+		    vd->vdev_ops->vdev_op_leaf) {
+			cmn_err(CE_WARN,
+			    "Disk, '%s', has a block alignment that is "
+			    "larger than the pool's alignment\n",
+			    vd->vdev_path);
 		}
 		vd->vdev_max_asize = max_asize;
 	}
--- a/usr/src/uts/common/io/scsi/targets/sd.c	Tue May 01 21:27:17 2012 +0100
+++ b/usr/src/uts/common/io/scsi/targets/sd.c	Thu May 03 05:49:19 2012 -0700
@@ -4220,6 +4220,18 @@
 		    "RMW type set to %d\n", un->un_f_rmw_type);
 	}
 
+	if (strcasecmp(name, "physical-block-size") == 0) {
+		if (ddi_strtol(value, &endptr, 0, &val) == 0 &&
+		    ISP2(val) && val >= un->un_tgt_blocksize &&
+		    val >= un->un_sys_blocksize) {
+			un->un_phy_blocksize = val;
+		} else {
+			goto value_invalid;
+		}
+		SD_INFO(SD_LOG_ATTACH_DETACH, un, "sd_set_properties: "
+		    "physical block size set to %d\n", un->un_phy_blocksize);
+	}
+
 	/*
 	 * Validate the throttle values.
 	 * If any of the numbers are invalid, set everything to defaults.
@@ -7620,6 +7632,13 @@
 	un->un_f_mmc_gesn_polling = TRUE;
 
 	/*
+	 * physical sector size defaults to DEV_BSIZE currently. We can
+	 * override this value via the driver configuration file so we must
+	 * set it before calling sd_read_unit_properties().
+	 */
+	un->un_phy_blocksize = DEV_BSIZE;
+
+	/*
 	 * Retrieve the properties from the static driver table or the driver
 	 * configuration file (.conf) for this unit and update the soft state
 	 * for the device as needed for the indicated properties.
@@ -7664,11 +7683,6 @@
 	un->un_blockcount = 0;
 
 	/*
-	 * physical sector size default to DEV_BSIZE currently.
-	 */
-	un->un_phy_blocksize = DEV_BSIZE;
-
-	/*
 	 * Set up the per-instance info needed to determine the correct
 	 * CDBs and other info for issuing commands to the target.
 	 */
@@ -23478,10 +23492,17 @@
 	 * Now read the capacity so we can provide the lbasize,
 	 * pbsize and capacity.
 	 */
-	if (dki_pbsize && un->un_f_descr_format_supported)
+	if (dki_pbsize && un->un_f_descr_format_supported) {
 		rval = sd_send_scsi_READ_CAPACITY_16(ssc, &capacity, &lbasize,
 		    &pbsize, SD_PATH_DIRECT);
 
+		/*
+		 * Override the physical blocksize if the instance already
+		 * has a larger value.
+		 */
+		pbsize = MAX(pbsize, un->un_phy_blocksize);
+	}
+
 	if (dki_pbsize == NULL || rval != 0 ||
 	    !un->un_f_descr_format_supported) {
 		rval = sd_send_scsi_READ_CAPACITY(ssc, &capacity, &lbasize,
@@ -31743,7 +31764,11 @@
 		} else {
 			if (!ISP2(pbsize % DEV_BSIZE) || pbsize == 0) {
 				un->un_phy_blocksize = DEV_BSIZE;
-			} else {
+			} else if (pbsize > un->un_phy_blocksize) {
+				/*
+				 * Don't reset the physical blocksize
+				 * unless we've detected a larger value.
+				 */
 				un->un_phy_blocksize = pbsize;
 			}
 		}