This patch fixes some issues related to disk formatting. First, it queries the disk to determine the optimal timeout to use for a format command. This fixes format timeout issues on very large capacity disks. Second, this also fixes up the 5xx/4k sector size handling to ensure we don't end up mistakenly reformatting drives to the wrong block size. This was primarily an issue for drives that ended up in medium format corrupt and the subsequent format then did the wrong thing.
Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> --- iprlib.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ iprlib.h | 16 ++++++++++-- 2 files changed, 90 insertions(+), 9 deletions(-) diff -puN iprlib.h~iprutils_c7 iprlib.h --- iprutils.patched/iprlib.h~iprutils_c7 2016-07-13 17:38:08.574276405 -0500 +++ iprutils.patched-bjking1/iprlib.h 2016-07-13 17:38:08.583276361 -0500 @@ -1481,6 +1481,10 @@ struct ipr_dev { u32 is_suspend_cand:1; u32 is_resume_cand:1; u8 write_cache_policy:1; + u8 supports_4k:1; + u8 supports_5xx:1; + u8 read_c7:1; + u32 format_timeout; struct scsi_dev_data *scsi_dev_data; struct ipr_dev *ses[IPR_DEV_MAX_PATHS]; struct ipr_res_addr res_addr[IPR_DEV_MAX_PATHS]; @@ -2692,9 +2696,17 @@ struct ipr_sas_inquiry_pageC7 { u8 reserved1; u8 page_length; u8 ascii_len; - u8 reserved2[109]; + u8 reserved2[38]; + u8 format_timeout_hi; /* in minutes */ + u8 format_timeout_lo; + u8 reserved3[63]; + u8 support_4k_modes; +#define ONLY_5XX_SUPPORTED 0 +#define BOTH_5XXe_OR_4K_SUPPORTED 1 +#define ONLY_4K_SUPPORTED 2 + u8 reserved4[5]; u8 total_bytes_warranty[IPR_SAS_INQ_BYTES_WARRANTY_LEN]; - u8 reserved3[43]; + u8 reserved5[43]; }; static inline int ipr_elem_offset(struct ipr_ses_config_pg *ses_cfg, u8 type) diff -puN iprlib.c~iprutils_c7 iprlib.c --- iprutils.patched/iprlib.c~iprutils_c7 2016-07-13 17:38:08.578276385 -0500 +++ iprutils.patched-bjking1/iprlib.c 2016-07-13 17:38:08.585276351 -0500 @@ -6423,6 +6423,74 @@ int ipr_get_logical_block_size(struct ip } /** + * init_inquiry_c7 - Page 0xC7 Inquiry to disks + * @dev: ipr dev struct + * + * Setup IBM vendor unique settings + * + * Returns: + * 0 if success / other on failure + **/ +static int init_inquiry_c7(struct ipr_dev *dev) +{ + struct ipr_sas_inquiry_pageC7 inq; + int rc; + + if (dev->read_c7) + return 0; + + if (!dev->scsi_dev_data || strncmp(dev->scsi_dev_data->vendor_id, "IBM", 3)) { + if (ipr_is_gscsi(dev)) { + if (ipr_get_logical_block_size(dev) == IPR_JBOD_4K_BLOCK_SIZE) { + dev->block_dev_class |= IPR_BLK_DEV_CLASS_4K; + dev->supports_4k = 1; + } else { + dev->block_dev_class &= ~IPR_BLK_DEV_CLASS_4K; + dev->supports_5xx = 1; + } + } + + dev->format_timeout = IPR_FORMAT_UNIT_TIMEOUT; + scsi_dbg(dev, "Skipping IBM vendor settings for non IBM device.\n"); + return -EINVAL; + } + + memset(&inq, 0, sizeof(inq)); + + rc = ipr_inquiry(dev, 0xC7, &inq, sizeof(inq)); + + if (rc) { + scsi_dbg(dev, "Inquiry 0xC7 failed. rc=%d\n", rc); + return rc; + } + + switch (inq.support_4k_modes) { + case ONLY_5XX_SUPPORTED: + dev->supports_5xx = 1; + dev->supports_4k = 0; + dev->block_dev_class &= ~IPR_BLK_DEV_CLASS_4K; + scsi_dbg(dev, "Only 5xx supported.\n"); + break; + case ONLY_4K_SUPPORTED: + dev->supports_4k = 1; + dev->block_dev_class |= IPR_BLK_DEV_CLASS_4K; + scsi_dbg(dev, "Only 4k supported.\n"); + break; + case BOTH_5XXe_OR_4K_SUPPORTED: + default: + dev->supports_5xx = 1; + dev->supports_4k = 1; + dev->block_dev_class |= IPR_BLK_DEV_CLASS_4K; + scsi_dbg(dev, "Both 4k and 5xx supported.\n"); + break; + }; + + dev->read_c7 = 1; + dev->format_timeout = ((inq.format_timeout_hi << 8) | inq.format_timeout_lo) * 60; + return 0; +} + +/** * check_current_config - populates the ioa configuration data * @allow_rebuild_refresh: allow_rebuild_refresh flag * @@ -6524,10 +6592,6 @@ void check_current_config(bool allow_reb IPR_DEV_CACHE_WRITE_THROUGH; } - if (scsi_dev_data->type == TYPE_DISK) { - if (ipr_get_logical_block_size(&ioa->dev[device_count]) == IPR_JBOD_4K_BLOCK_SIZE) - ioa->dev[device_count].block_dev_class |= IPR_BLK_DEV_CLASS_4K; - } /* find array config data matching resource entry */ k = 0; for_each_qac_entry(common_record, qac_data) { @@ -6627,7 +6691,10 @@ void check_current_config(bool allow_reb for_each_ra(ra, dev) memcpy(ra, &res_addr, sizeof(*ra)); - if (!dev || !dev->qac_entry) + if (ipr_is_gscsi(dev) || ipr_is_af_dasd_device(dev)) + init_inquiry_c7(dev); + + if (!dev->qac_entry) continue; if (dev->qac_entry->record_id == IPR_RECORD_ID_DEVICE_RECORD) { @@ -7207,7 +7274,9 @@ static int get_format_timeout(struct ipr int rc, i, records, timeout; char temp[100]; - if (ipr_is_af_dasd_device(dev)) { + rc = init_inquiry_c7(dev); + + if (rc && ipr_is_af_dasd_device(dev)) { rc = ipr_query_dasd_timeouts(dev, &tos); if (!rc) { @@ -7227,7 +7296,7 @@ static int get_format_timeout(struct ipr } } - timeout = IPR_FORMAT_UNIT_TIMEOUT; + timeout = dev->format_timeout; rc = ipr_get_saved_dev_attr(dev, IPR_FORMAT_TIMEOUT, temp); if (rc == RC_SUCCESS) sscanf(temp, "%d", &timeout); _ ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports.http://sdm.link/zohodev2dev _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel