From patchwork Fri Mar 1 22:44:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Adamson X-Patchwork-Id: 10836197 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 37E0E139A for ; Fri, 1 Mar 2019 22:42:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 234382FD52 for ; Fri, 1 Mar 2019 22:42:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 20CCB2FEC5; Fri, 1 Mar 2019 22:42:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 35C11300E8 for ; Fri, 1 Mar 2019 22:42:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726922AbfCAWma (ORCPT ); Fri, 1 Mar 2019 17:42:30 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:51668 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726693AbfCAWma (ORCPT ); Fri, 1 Mar 2019 17:42:30 -0500 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x21MYg4M087429; Fri, 1 Mar 2019 22:42:26 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id; s=corp-2018-07-02; bh=/hDf0jv/mJfutQqobWNlsNFlb5WsB9eD/U08UTiyyp4=; b=c3mOF3/d4/CkwHyMkmwm5Oyb0Jdu135PCRVMgY/WlqiFY+zK85wkoOPYSVMOKUgyNWFC LGZ4uxHPZGXrkmwgPt4vrVNz1J6R27X44LNWDGDD97n+ug5B+3XxVfmtHvLnzx6J1fJn +hzDGoesga4iQ/86Z+YgqR8biqf8JNOwrez+P19Xl0PARbS6c5pd0sxVrj5f6Rh8tlZ1 JGMtt9H/+w1rGrqReUDW9Ws/xB5ZXfU43Iyd7VMBwVgcgzcO/5C1zQNP5es7LRCYOe/q RYR5cN80j1839Q6euisR92soEdgqBEirdhyOtuFuI6Rfqu9+wXfFd8NGkz4pgTFMnkYH KA== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2130.oracle.com with ESMTP id 2qtupet9qp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 01 Mar 2019 22:42:26 +0000 Received: from dhcp-10-141-197-146.usdhcp.oraclecorp.com.com (dhcp-10-141-197-146.usdhcp.oraclecorp.com [10.141.197.146]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x21MgLxw022823; Fri, 1 Mar 2019 22:42:21 GMT From: Alan Adamson To: target-devel@vger.kernel.org Cc: nab@linux-iscsi.org, linux-scsi@vger.kernel.org Subject: [PATCH] scsi: target: add device product id and revision configfs attributes Date: Fri, 1 Mar 2019 14:44:20 -0800 Message-Id: <1551480260-1265-1-git-send-email-alan.adamson@oracle.com> X-Mailer: git-send-email 1.8.3.1 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9182 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=21 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1903010154 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The product_id and revision attributes will allow for the modification of the T10 Model and Revision strings returned in inquiry responses. Its value can be viewed and modified via the ConfigFS path at: target/core/$backstore/$name/wwn/product_id target/core/$backstore/$name/wwn/revision Signed-off-by: Alan Adamson Reviewed-by: Martin K. Petersen Reviewed-by: Bart Van Assche --- drivers/target/target_core_configfs.c | 157 ++++++++++++++++++++++++++++++---- 1 file changed, 142 insertions(+), 15 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 8e7fffbb8802..a405733e30d9 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1231,6 +1231,29 @@ static struct t10_wwn *to_t10_wwn(struct config_item *item) return container_of(to_config_group(item), struct t10_wwn, t10_wwn_group); } +static ssize_t target_check_inquiry_data(char *buf) +{ + size_t len; + int i; + + len = strlen(buf); + + /* + * SPC 4.3.1: + * ASCII data fields shall contain only ASCII printable characters + * (i.e., code values 20h to 7Eh) and may be terminated with one or + * more ASCII null (00h) characters. + */ + for (i = 0; i < len; i++) { + if ((buf[i] < 0x20) || (buf[i] > 0x7E)) { + pr_err("Emulated T10 Inquiry Data contains non-ASCII-printable characters\n"); + return -EINVAL; + } + } + + return len; +} + /* * STANDARD and VPD page 0x83 T10 Vendor Identification */ @@ -1248,8 +1271,7 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ unsigned char buf[INQUIRY_VENDOR_LEN + 2]; char *stripped = NULL; - size_t len; - int i; + size_t len, ret; len = strlcpy(buf, page, sizeof(buf)); if (len < sizeof(buf)) { @@ -1264,19 +1286,10 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, return -EOVERFLOW; } - /* - * SPC 4.3.1: - * ASCII data fields shall contain only ASCII printable characters (i.e., - * code values 20h to 7Eh) and may be terminated with one or more ASCII - * null (00h) characters. - */ - for (i = 0; i < len; i++) { - if ((stripped[i] < 0x20) || (stripped[i] > 0x7E)) { - pr_err("Emulated T10 Vendor Identification contains" - " non-ASCII-printable characters\n"); - return -EINVAL; - } - } + ret = target_check_inquiry_data(stripped); + + if (ret < 0) + return ret; /* * Check to see if any active exports exist. If they do exist, fail @@ -1299,6 +1312,116 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, return count; } +static ssize_t target_wwn_product_id_show(struct config_item *item, + char *page) +{ + return sprintf(page, "%s\n", &to_t10_wwn(item)->model[0]); +} + +static ssize_t target_wwn_product_id_store(struct config_item *item, + const char *page, size_t count) +{ + struct t10_wwn *t10_wwn = to_t10_wwn(item); + struct se_device *dev = t10_wwn->t10_dev; + /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ + unsigned char buf[INQUIRY_MODEL_LEN + 2]; + char *stripped = NULL; + size_t len, ret; + + len = strlcpy(buf, page, sizeof(buf)); + if (len < sizeof(buf)) { + /* Strip any newline added from userspace. */ + stripped = strstrip(buf); + len = strlen(stripped); + } + if (len > INQUIRY_MODEL_LEN) { + pr_err("Emulated T10 Vendor exceeds INQUIRY_MODEL_LEN: " + __stringify(INQUIRY_MODEL_LEN) + "\n"); + return -EOVERFLOW; + } + + ret = target_check_inquiry_data(stripped); + + if (ret < 0) + return ret; + + /* + * Check to see if any active exports exist. If they do exist, fail + * here as changing this information on the fly (underneath the + * initiator side OS dependent multipath code) could cause negative + * effects. + */ + if (dev->export_count) { + pr_err("Unable to set T10 Model while active %d exports exist\n", + dev->export_count); + return -EINVAL; + } + + BUILD_BUG_ON(sizeof(dev->t10_wwn.model) != INQUIRY_MODEL_LEN + 1); + strlcpy(dev->t10_wwn.model, stripped, sizeof(dev->t10_wwn.model)); + + pr_debug("Target_Core_ConfigFS: Set emulated T10 Model Identification: %s\n", + dev->t10_wwn.model); + + return count; +} + +static ssize_t target_wwn_revision_show(struct config_item *item, + char *page) +{ + return sprintf(page, "%s\n", &to_t10_wwn(item)->revision[0]); +} + +static ssize_t target_wwn_revision_store(struct config_item *item, + const char *page, size_t count) +{ + struct t10_wwn *t10_wwn = to_t10_wwn(item); + struct se_device *dev = t10_wwn->t10_dev; + /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ + unsigned char buf[INQUIRY_REVISION_LEN + 2]; + char *stripped = NULL; + size_t len, ret; + + len = strlcpy(buf, page, sizeof(buf)); + if (len < sizeof(buf)) { + /* Strip any newline added from userspace. */ + stripped = strstrip(buf); + len = strlen(stripped); + } + if (len > INQUIRY_REVISION_LEN) { + pr_err("Emulated T10 Revision exceeds INQUIRY_REVISION_LEN: " + __stringify(INQUIRY_REVISION_LEN) + "\n"); + return -EOVERFLOW; + } + + ret = target_check_inquiry_data(stripped); + + if (ret < 0) + return ret; + + /* + * Check to see if any active exports exist. If they do exist, fail + * here as changing this information on the fly (underneath the + * initiator side OS dependent multipath code) could cause negative + * effects. + */ + if (dev->export_count) { + pr_err("Unable to set T10 Revision while active %d exports exist\n", + dev->export_count); + return -EINVAL; + } + + BUILD_BUG_ON(sizeof(dev->t10_wwn.revision) != INQUIRY_REVISION_LEN + 1); + strlcpy(dev->t10_wwn.revision, stripped, sizeof(dev->t10_wwn.revision)); + + pr_debug("Target_Core_ConfigFS: Set emulated T10 Revision: %s\n", + dev->t10_wwn.revision); + + return count; +} + /* * VPD page 0x80 Unit serial */ @@ -1446,6 +1569,8 @@ static ssize_t target_wwn_vpd_protocol_identifier_show(struct config_item *item, DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_scsi_target_device, 0x20); CONFIGFS_ATTR(target_wwn_, vendor_id); +CONFIGFS_ATTR(target_wwn_, product_id); +CONFIGFS_ATTR(target_wwn_, revision); CONFIGFS_ATTR(target_wwn_, vpd_unit_serial); CONFIGFS_ATTR_RO(target_wwn_, vpd_protocol_identifier); CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_logical_unit); @@ -1454,6 +1579,8 @@ static ssize_t target_wwn_vpd_protocol_identifier_show(struct config_item *item, static struct configfs_attribute *target_core_dev_wwn_attrs[] = { &target_wwn_attr_vendor_id, + &target_wwn_attr_product_id, + &target_wwn_attr_revision, &target_wwn_attr_vpd_unit_serial, &target_wwn_attr_vpd_protocol_identifier, &target_wwn_attr_vpd_assoc_logical_unit,