diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/zpool/zpool_main.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/vdev.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/io/scsi/targets/sd.c | 39 |
3 files changed, 42 insertions, 13 deletions
diff --git a/usr/src/cmd/zpool/zpool_main.c b/usr/src/cmd/zpool/zpool_main.c index 3083375060..6a6b88c730 100644 --- a/usr/src/cmd/zpool/zpool_main.c +++ b/usr/src/cmd/zpool/zpool_main.c @@ -3703,7 +3703,7 @@ print_dedup_stats(nvlist_t *config) /* * 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, diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c index 094d4c92de..6606b1f486 100644 --- a/usr/src/uts/common/fs/zfs/vdev.c +++ b/usr/src/uts/common/fs/zfs/vdev.c @@ -1244,12 +1244,16 @@ vdev_open(vdev_t *vd) 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; } diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c index d3f0edf11b..501bca39c8 100644 --- a/usr/src/uts/common/io/scsi/targets/sd.c +++ b/usr/src/uts/common/io/scsi/targets/sd.c @@ -4220,6 +4220,18 @@ sd_set_properties(struct sd_lun *un, char *name, char *value) "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 @@ sd_unit_attach(dev_info_t *devi) 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 @@ sd_unit_attach(dev_info_t *devi) 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 @@ sd_get_media_info_com(dev_t dev, uint_t *dki_media_type, uint_t *dki_lbsize, * 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 @@ sd_check_emulation_mode(sd_ssc_t *ssc) } 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; } } |